- preliminary support for installation of source packages (FATE #301171), without...
authorJan Kupec <jkupec@suse.cz>
Mon, 6 Aug 2007 14:06:42 +0000 (14:06 +0000)
committerJan Kupec <jkupec@suse.cz>
Mon, 6 Aug 2007 14:06:42 +0000 (14:06 +0000)
doc/zypper.8
src/zypper-command.cc
src/zypper-command.h
src/zypper-misc.cc
src/zypper-misc.h
src/zypper.cc
src/zypper.h

index 9e65071..5b0a4c1 100644 (file)
@@ -77,6 +77,12 @@ directory to your bug report. To use this option, simply add it to the problemat
 install or remove command. 
 
 .TP
+.B source-install (si) <name>
+Install a source package specified by its name.
+
+This command will try to find the newest available version of the source package and use rpm -i to install it.
+
+.TP
 .B list-updates (lu) [options]
 List available updates.
 .TP
index bebb52e..4c8c6e6 100644 (file)
@@ -26,6 +26,7 @@ const ZypperCommand ZypperCommand::REFRESH(ZypperCommand::REFRESH_e);
 const ZypperCommand ZypperCommand::INSTALL(ZypperCommand::INSTALL_e);
 const ZypperCommand ZypperCommand::REMOVE(ZypperCommand::REMOVE_e);
 const ZypperCommand ZypperCommand::UPDATE(ZypperCommand::UPDATE_e);
+const ZypperCommand ZypperCommand::SRC_INSTALL(ZypperCommand::SRC_INSTALL_e);
 
 const ZypperCommand ZypperCommand::SEARCH(ZypperCommand::SEARCH_e);
 const ZypperCommand ZypperCommand::INFO(ZypperCommand::INFO_e);
@@ -63,6 +64,7 @@ ZypperCommand::Command ZypperCommand::parse(const std::string & strval_r)
     _table["install"] = _table["in"] = ZypperCommand::INSTALL_e;
     _table["remove"] = _table["rm"] = ZypperCommand::REMOVE_e;
     _table["update"] = _table["up"] = ZypperCommand::UPDATE_e;
+    _table["source-install"] = _table["si"] = ZypperCommand::SRC_INSTALL_e;
 
     _table["search"] = _table["se"] = ZypperCommand::SEARCH_e;
     _table["info"] = _table["if"] = ZypperCommand::INFO_e;
index cb9e5da..c9da0e9 100644 (file)
@@ -20,6 +20,7 @@ struct ZypperCommand
   static const ZypperCommand INSTALL;
   static const ZypperCommand REMOVE;
   static const ZypperCommand UPDATE;
+  static const ZypperCommand SRC_INSTALL;
   
   static const ZypperCommand SEARCH;
   static const ZypperCommand INFO;
@@ -53,6 +54,7 @@ struct ZypperCommand
     INSTALL_e,
     REMOVE_e,
     UPDATE_e,
+    SRC_INSTALL_e,
     
     SEARCH_e,
     INFO_e,
index 0e9fd56..263b153 100644 (file)
@@ -4,6 +4,8 @@
 #include <boost/logic/tribool_io.hpp>
 
 #include <zypp/Patch.h>
+#include <zypp/Package.h>
+#include <zypp/SrcPackage.h>
 #include <zypp/base/Algorithm.h>
 #include <zypp/solver/detail/Helper.h>
 
@@ -456,16 +458,15 @@ std::string calculate_token()
 }
 */
 
-void cond_load_resolvables()
+void cond_load_resolvables(bool to_pool)
 {      
-  load_repo_resolvables();
-  if ( ! gSettings.disable_system_resolvables ) {
+  load_repo_resolvables(to_pool);
+  if (!gSettings.disable_system_resolvables && to_pool)
     load_target_resolvables();
-  }
 }
 
 /** read repository resolvables */
-void load_repo_resolvables()
+void load_repo_resolvables(bool to_pool)
 {
   RepoManager manager;
 
@@ -503,7 +504,10 @@ void load_repo_resolvables()
       ResStore store = repository.resolvables();
       cout_v << " " << format(_("(%d resolvables found)")) % store.size() << endl;
 
-      God->addResolvables(store);
+      if (to_pool)
+        God->addResolvables(store);
+      else
+        gData.repo_resolvables.insert(store.begin(), store.end());
     }
     catch (const repo::RepoMetadataException & ex)
     {
@@ -521,7 +525,7 @@ void load_repo_resolvables()
   }
 }
 
-void load_target_resolvables()
+void load_target_resolvables(bool to_pool)
 {
   if (!gSettings.machine_readable)
     cout_n << _("Reading RPM database...");
@@ -536,7 +540,10 @@ void load_target_resolvables()
   }
   DBG << tgt_resolvables.size() << " resolvables read";
 
-  God->addResolvables(tgt_resolvables, true /*installed*/);
+  if (to_pool)
+    God->addResolvables(tgt_resolvables, true /*installed*/);
+  else
+    gData.target_resolvables = tgt_resolvables;
 }
 
 void establish ()
@@ -1239,6 +1246,86 @@ bool confirm_licenses()
   return confirmed;
 }
 
+
+struct FindSrcPackage
+{
+  FindSrcPackage(SrcPackage::Ptr & srcpkg) : _srcpkg(srcpkg) {}
+
+  bool operator() (ResObject::Ptr res)
+  {
+    SrcPackage::Ptr srcpkg = asKind<SrcPackage>(res);
+    cout_vv << "Considering srcpakcage " << srcpkg->name() << "-" << srcpkg->edition() << ": ";
+    if (_srcpkg)
+    {
+      if (_srcpkg->edition() < srcpkg->edition())
+        cout_vv << "newer edition (" << srcpkg->edition() << " > " << _srcpkg->edition() << ")" << endl;
+      else
+        cout_vv << "is older than the current candidate";
+    }
+    else
+      cout_vv << "first candindate";
+
+    cout_vv << endl;
+
+    _srcpkg.swap(srcpkg);
+
+    return true;
+  }
+
+  SrcPackage::Ptr & _srcpkg;
+};
+
+
+int source_install(std::vector<std::string> & arguments)
+{
+  /*
+   * Workflow:
+   * 
+   * 1. load repo resolvables (to gData.repo_resolvables) 
+   * 2. interate all SrcPackage resolvables with specified name
+   * 3. find the latest version or version satisfying specification.
+   * 4. install the source package with ZYpp->installSrcPackage(SrcPackage::constPtr);
+   */
+
+  SrcPackage::Ptr srcpkg;
+
+  gData.repo_resolvables.forEach(
+    functor::chain(
+      resfilter::ByName(arguments[0]),
+      resfilter::ByKind(ResTraits<SrcPackage>::kind)),
+      FindSrcPackage(srcpkg));
+
+  if (srcpkg)
+  {
+    cout << format(_("Installing source package %s-%s"))
+        % srcpkg->name() % srcpkg->edition() << endl;
+    MIL << "Going to install srcpackage: " << srcpkg << endl;
+
+    try
+    {
+      God->installSrcPackage(srcpkg);
+      
+      cout << format(_("Source package %s-%s successfully installed."))
+          % srcpkg->name() % srcpkg->edition() << endl;
+
+      return ZYPPER_EXIT_OK;  
+    }
+    catch (const Exception & ex)
+    {
+      ZYPP_CAUGHT(ex);
+      cerr << format(_("Problem installing source package %s-%s:"))
+          % srcpkg->name() % srcpkg->edition() << endl;
+      cerr << ex.asUserString() << endl;
+
+      return ZYPPER_EXIT_ERR_ZYPP;
+    }
+  }
+  else
+    cerr << format(_("Source package '%s' not found.")) % arguments[0] << endl;
+
+  return ZYPPER_EXIT_OK;
+}
+
 // Local Variables:
 // c-basic-offset: 2
 // End:
index 27fb6a2..bf305de 100644 (file)
@@ -42,20 +42,34 @@ int show_summary();
 //std::string calculate_token();
 
 /**
- * Load both repository and target resolvables into the pool respecting
- * user defined conditions.
+ * Load both repository and target resolvables.
+ * 
+ * \param to_pool If <tt>true</tt>, the resolvables are added to the pool, if
+ *        <tt>false</tt> they will be stored in \ref gData.repo_resolvalbes
+ *        and \ref gData.target_resolvables (global ResStore vector).
+ * 
+ * \see load_repo_resolvables(bool)
+ * \see load_target_resolvables(bool)
  */
-void cond_load_resolvables ();
+void cond_load_resolvables(bool to_pool = true);
 
 /**
- * Load resolvables from all repositories into the pool. 
+ * Reads resolvables from the RPM database (installed resolvables) into the pool.
+ * 
+ * \param to_pool If <tt>true</tt>, the resolvables are added to the pool, if
+ *        <tt>false</tt> they will be stored \ref gData.target_resolvables
+ *        (global ResStore variable).
  */
-void load_target_resolvables();
+void load_target_resolvables(bool to_pool = true);
 
 /**
- * Load installed resolvables from target into the pool.
+ * Reads resolvables from the repository sqlite cache. 
+ * 
+ * \param to_pool If <tt>true</tt>, the resolvables are added to the pool, if
+ *        <tt>false</tt> they will be stored in \ref gData.repo_resolvables
+ *        (global ResStore vector).
  */
-void load_repo_resolvables();
+void load_repo_resolvables(bool to_pool = true);
 
 void establish ();
 bool resolve();
@@ -131,4 +145,9 @@ struct ProvideProcess
   bool operator()( const zypp::PoolItem& provider );
 };
 
+/**
+ * Installs source packages specified by name.
+ */
+int source_install(std::vector<std::string> & arguments);
+
 #endif
index e625d54..97b7d6e 100644 (file)
@@ -138,6 +138,7 @@ ZypperCommand process_globals(int argc, char **argv)
     "\tupdate, up\t\tUpdate installed resolvables with newer versions.\n"
     "\tinfo, if\t\tShow full information for packages\n"
     "\tpatch-info\t\tShow full information for patches\n"
+    "\tsource-install, si\tInstall a source package\n"
     "");
 
   if (gopts.count("rug-compatible"))
@@ -280,10 +281,10 @@ int one_command(const ZypperCommand & command, int argc, char **argv)
     // (package, patch, pattern, product) or at least leave also their
     // originals, since they are expected untranslated on the command line
     specific_help = _(
-      "install [options] <capability> ...\n"
+      "install (in) [options] <capability> ...\n"
       "\n"
-      "'install' - Install resolvables with specified capabilities. A capability is\n"
-      "            NAME[ OP <VERSION>], where OP is one of <, <=, =, >=, >.\n"
+      "Install resolvables with specified capabilities. A capability is"
+      " NAME[ OP <VERSION>], where OP is one of <, <=, =, >=, >.\n"
       "\n"
       "  Command options:\n"
       "-r, --repo <alias>              Install resolvables only from repository specified by alias.\n"
@@ -309,10 +310,10 @@ int one_command(const ZypperCommand & command, int argc, char **argv)
     };
     specific_options = remove_options;
     specific_help = _(
-      "remove [options] <capability> ...\n"
+      "remove (rm) [options] <capability> ...\n"
       "\n"
-      "'remove' - Remove resolvables with specified capabilities. A capability is\n"
-      "            NAME[ OP <VERSION>], where OP is one of <, <=, =, >=, >.\n"
+      "Remove resolvables with specified capabilities. A capability is"
+      " NAME[ OP <VERSION>], where OP is one of <, <=, =, >=, >.\n"
       "\n"
       "  Command options:\n"
       "-r, --repo <alias> Operate only with resolvables from repository specified by alias.\n"
@@ -321,6 +322,20 @@ int one_command(const ZypperCommand & command, int argc, char **argv)
       "    --debug-solver Create solver test case for debugging\n"  
     );
   }
+  else if (command == ZypperCommand::SRC_INSTALL) {
+    static struct option src_install_options[] = {
+      {"help", no_argument, 0, 'h'},
+      {0, 0, 0, 0}
+    };
+    specific_options = src_install_options;
+    specific_help = _(
+      "source-install (si) <name>\n"
+      "\n"
+      "Install a source package specified by its name.\n"
+      "\n"
+      "This command has no additional options.\n"
+    );
+  }
   else if (command == ZypperCommand::ADD_REPO) {
     static struct option service_add_options[] = {
       {"type", required_argument, 0, 't'},
@@ -652,7 +667,7 @@ int one_command(const ZypperCommand & command, int argc, char **argv)
     cout_v << _("Non-option program arguments: ");
     while (optind < argc) {
       string argument = argv[optind++];
-      cout_v << argument << ' ';
+      cout_v << "'" << argument << "' ";
       arguments.push_back (argument);
     }
     cout_v << endl;
@@ -1073,6 +1088,32 @@ int one_command(const ZypperCommand & command, int argc, char **argv)
     return ZYPPER_EXIT_OK;
   }
 
+  // -------------------( source install )------------------------------------
+
+  else if (command == ZypperCommand::SRC_INSTALL)
+  {
+    if (ghelp)
+    {
+      cout << specific_help;
+      return ZYPPER_EXIT_OK;
+    }
+
+    if (arguments.size() < 1)
+    {
+      cerr << _("Source package name is a required argument.") << endl;
+      return ZYPPER_EXIT_ERR_INVALID_ARGS;
+    }
+
+    int initret = init_repos();
+    if (initret != ZYPPER_EXIT_OK)
+      return initret;
+    cond_init_target();
+    // load only repo resolvables, we don't need the installed ones
+    load_repo_resolvables(false /* don't load to pool */);
+
+    return source_install(arguments);
+  }
+
   // --------------------------( search )-------------------------------------
 
   // TODO -c, --catalog option
index 99acbc7..959c734 100644 (file)
@@ -95,13 +95,15 @@ struct RuntimeData
   : patches_count(0),
   security_patches_count(0)
   {}
-    
+
   std::list<Error> errors;
   std::list<zypp::RepoInfo> repos;
   int patches_count;
   int security_patches_count;
   std::vector<std::string> packages_to_install; 
   std::vector<std::string> packages_to_uninstall; 
+  zypp::ResStore repo_resolvables;
+  zypp::ResStore target_resolvables;
 };
 
 extern RuntimeData gData;