From c2e0506453f8fad634d4ac56a651fe1dbbd9f697 Mon Sep 17 00:00:00 2001 From: Jan Kupec Date: Mon, 6 Aug 2007 14:06:42 +0000 Subject: [PATCH] - preliminary support for installation of source packages (FATE #301171), without possibility to specify version to install and to install its dependencies along --- doc/zypper.8 | 6 +++ src/zypper-command.cc | 2 + src/zypper-command.h | 2 + src/zypper-misc.cc | 103 ++++++++++++++++++++++++++++++++++++++++++++++---- src/zypper-misc.h | 33 ++++++++++++---- src/zypper.cc | 55 +++++++++++++++++++++++---- src/zypper.h | 4 +- 7 files changed, 182 insertions(+), 23 deletions(-) diff --git a/doc/zypper.8 b/doc/zypper.8 index 9e65071..5b0a4c1 100644 --- a/doc/zypper.8 +++ b/doc/zypper.8 @@ -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) +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 diff --git a/src/zypper-command.cc b/src/zypper-command.cc index bebb52e..4c8c6e6 100644 --- a/src/zypper-command.cc +++ b/src/zypper-command.cc @@ -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; diff --git a/src/zypper-command.h b/src/zypper-command.h index cb9e5da..c9da0e9 100644 --- a/src/zypper-command.h +++ b/src/zypper-command.h @@ -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, diff --git a/src/zypper-misc.cc b/src/zypper-misc.cc index 0e9fd56..263b153 100644 --- a/src/zypper-misc.cc +++ b/src/zypper-misc.cc @@ -4,6 +4,8 @@ #include #include +#include +#include #include #include @@ -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(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 & 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::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: diff --git a/src/zypper-misc.h b/src/zypper-misc.h index 27fb6a2..bf305de 100644 --- a/src/zypper-misc.h +++ b/src/zypper-misc.h @@ -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 true, the resolvables are added to the pool, if + * false 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 true, the resolvables are added to the pool, if + * false 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 true, the resolvables are added to the pool, if + * false 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 & arguments); + #endif diff --git a/src/zypper.cc b/src/zypper.cc index e625d54..97b7d6e 100644 --- a/src/zypper.cc +++ b/src/zypper.cc @@ -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] ...\n" + "install (in) [options] ...\n" "\n" - "'install' - Install resolvables with specified capabilities. A capability is\n" - " NAME[ OP ], where OP is one of <, <=, =, >=, >.\n" + "Install resolvables with specified capabilities. A capability is" + " NAME[ OP ], where OP is one of <, <=, =, >=, >.\n" "\n" " Command options:\n" "-r, --repo 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] ...\n" + "remove (rm) [options] ...\n" "\n" - "'remove' - Remove resolvables with specified capabilities. A capability is\n" - " NAME[ OP ], where OP is one of <, <=, =, >=, >.\n" + "Remove resolvables with specified capabilities. A capability is" + " NAME[ OP ], where OP is one of <, <=, =, >=, >.\n" "\n" " Command options:\n" "-r, --repo 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) \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 diff --git a/src/zypper.h b/src/zypper.h index 99acbc7..959c734 100644 --- a/src/zypper.h +++ b/src/zypper.h @@ -95,13 +95,15 @@ struct RuntimeData : patches_count(0), security_patches_count(0) {} - + std::list errors; std::list repos; int patches_count; int security_patches_count; std::vector packages_to_install; std::vector packages_to_uninstall; + zypp::ResStore repo_resolvables; + zypp::ResStore target_resolvables; }; extern RuntimeData gData; -- 2.7.4