#
SET(VERSION_MAJOR "1")
SET(VERSION_MINOR "14")
-SET(VERSION_PATCH "13")
+SET(VERSION_PATCH "14")
-# LAST RELEASED: 1.14.13
+# LAST RELEASED: 1.14.14
#=======
-------------------------------------------------------------------
+Fri Oct 12 14:05:47 CEST 2018 - ma@suse.de
+
+- BuildRequires: libzypp-devel >= 17.8.0 (for fate#326451)
+- Introduce new zypper command framefork. Migrated commands so far:
+ addlock addrepo addservice clean cleanlocks modifyrepo modifyservice
+ ps refresh refresh-services removelock removerepo removeservice
+ renamerepo repos services
+- version 1.14.14
+
+-------------------------------------------------------------------
Tue Oct 9 17:30:45 CEST 2018 - ma@suse.de
- MediaChangeReport: fix https URLs causing 2 prompts on error
"Project-Id-Version: zypper.de\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-09-21 12:17+0200\n"
-"PO-Revision-Date: 2018-08-30 21:02+0000\n"
+"PO-Revision-Date: 2018-10-09 23:02+0000\n"
"Last-Translator: Sarah Kriesch <ada.lovelace@gmx.de>\n"
-"Language-Team: German <https://l10n.opensuse.org/projects/zypper/master/de/"
-">\n"
+"Language-Team: German <https://l10n.opensuse.org/projects/zypper/master/de/>"
+"\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgstr ""
#: src/commands/basecommand.cc:134
-#, fuzzy
msgid "Options:"
-msgstr "optional"
+msgstr "Optionen:"
#. translators: property name; short; used like "Name: value"
#. translators: Table column header
"Project-Id-Version: zypper\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-09-21 12:17+0200\n"
-"PO-Revision-Date: 2018-08-30 19:09+0000\n"
-"Last-Translator: Rodrigo Macedo <rmsolucoeseminformatic4@gmail.com>\n"
-"Language-Team: Portuguese (Brazil) <https://l10n.opensuse.org/projects/"
-"zypper/master/pt_BR/>\n"
+"PO-Revision-Date: 2018-10-09 21:05+0000\n"
+"Last-Translator: Luiz Fernando Ranghetti <elchevive68@gmail.com>\n"
+"Language-Team: Portuguese (Brazil) "
+"<https://l10n.opensuse.org/projects/zypper/master/pt_BR/>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
#. translator: Option argument like '--export <FILE.repo>'. Do do not translate lowercase wordparts
#: src/utils/flags/zyppflags.h:27
msgid "DIR"
-msgstr ""
+msgstr "DIR"
#. translator: Option argument like '--export <FILE.repo>'. Do do not translate lowercase wordparts
#: src/utils/flags/zyppflags.h:29
msgid "FILE"
-msgstr ""
+msgstr "ARQUIVO"
#. translator: Option argument like '--export <FILE.repo>'. Do do not translate lowercase wordparts
#: src/utils/flags/zyppflags.h:31
#. translator: Option argument like '--export <FILE.repo>'. Do do not translate lowercase wordparts
#: src/utils/flags/zyppflags.h:33
msgid "FORMAT"
-msgstr ""
+msgstr "FORMATO"
#. translator: Option argument like '--export <FILE.repo>'. Do do not translate lowercase wordparts
#: src/utils/flags/zyppflags.h:35
#. translator: Option argument like '--export <FILE.repo>'. Do do not translate lowercase wordparts
#: src/utils/flags/zyppflags.h:37
msgid "PATH"
-msgstr ""
+msgstr "CAMINHO"
#. translator: Option argument like '--export <FILE.repo>'. Do do not translate lowercase wordparts
#: src/utils/flags/zyppflags.h:39
#. translator: Option argument like '--export <FILE.repo>'. Do do not translate lowercase wordparts
#: src/utils/flags/zyppflags.h:41
msgid "STRING"
-msgstr ""
+msgstr "TEXTO"
#. translator: Option argument like '--export <FILE.repo>'. Do do not translate lowercase wordparts
#: src/utils/flags/zyppflags.h:43
msgid "TAG"
-msgstr ""
+msgstr "ETIQUETA"
#. translator: Option argument like '--export <FILE.repo>'. Do do not translate lowercase wordparts
#: src/utils/flags/zyppflags.h:45
#. translators: --plus-repo, -p <URI>
#: src/Zypper.cc:760
msgid "Use an additional repository."
-msgstr "Usar um repositório adicional"
+msgstr "Usar um repositório adicional."
#. translators: --plus-content <TAG>
#: src/Zypper.cc:762
#. translators: command summary: versioncmp, vcmp
#: src/Zypper.cc:878
msgid "Compare two version strings."
-msgstr "Comparar textos de duas versões"
+msgstr "Comparar textos de duas versões."
#. translators: command summary: targetos, tos
#: src/Zypper.cc:880
" --loose-auth Ignore user authentication data in the URI.\n"
" --loose-query Ignore query string in the URI.\n"
msgstr ""
+"removeservice (rs) [OPÇÕES] <apelido|#|URI>\n"
+"\n"
+"Remove o serviço de indexação de repositório especificado do sistema.\n"
+"\n"
+" Opções do comando:\n"
+" --loose-auth Ignora os dados de autenticação do usuário na URI.\n"
+" --loose-query Ignora o texto de consulta na URI.\n"
#. translators: %s is "--all" and "--all"
#: src/Zypper.cc:2463
#. translators: command synopsis; do not translate lowercase words
#: src/Zypper.cc:3113
msgid "update (up) [OPTIONS] [PACKAGENAME] ..."
-msgstr ""
+msgstr "update (up) [OPÇÕES] [NOME_DO_PACOTE] ..."
#. translators: command description
#: src/Zypper.cc:3116
msgid ""
"Update all or specified installed packages with newer versions, if possible."
msgstr ""
+"Atualiza todos os pacotes instalados ou os especificados com versões mais "
+"recentes, se possÃvel."
#. translators: --skip-interactive
#: src/Zypper.cc:3124
msgid "Skip interactive updates."
-msgstr ""
+msgstr "Ignora as atualizações interativas."
#. translators: --with-interactive
#: src/Zypper.cc:3126
msgid "Do not skip interactive updates."
-msgstr ""
+msgstr "Não ignorar as atualizações interativas."
#. translators: -l, --auto-agree-with-licenses
#: src/Zypper.cc:3128 src/Zypper.cc:3233 src/Zypper.cc:3394
#. translators: -D, --dry-run
#: src/Zypper.cc:3398
msgid "Test the upgrade, do not actually upgrade"
-msgstr "Testar a atualização, não atualizar realmente."
+msgstr "Testar a atualização, não atualizar realmente"
#: src/Zypper.cc:3451
msgid ""
#. translators: command synopsis; do not translate lowercase words
#: src/Zypper.cc:4006
msgid "moo"
-msgstr ""
+msgstr "moo"
#. translators: command description
#: src/Zypper.cc:4009
#. translators: command synopsis; do not translate the command 'name (abbreviations)' or '-option' names
#: src/Zypper.cc:4095
msgid "cleanlocks (cl)"
-msgstr ""
+msgstr "cleanlocks (cl)"
#. translators: command description
#: src/Zypper.cc:4098
#. translators: command synopsis; do not translate lowercase words
#: src/Zypper.cc:4186
msgid "licenses"
-msgstr ""
+msgstr "licenses"
#. translators: command description
#: src/Zypper.cc:4189
#. translators: command synopsis; do not translate lowercase words
#: src/Zypper.cc:4309
msgid "source-download"
-msgstr ""
+msgstr "source-download"
#. translators: -d, --directory <DIR>
#: src/Zypper.cc:4316
#. translators: command synopsis; do not translate lowercase words
#: src/Zypper.cc:4355
msgid "quit (exit, ^D)"
-msgstr ""
+msgstr "quit (exit, ^D)"
#. translators: command description
#: src/Zypper.cc:4358
#. translators: command synopsis; do not translate lowercase words
#: src/Zypper.cc:4383
msgid "shell (sh)"
-msgstr ""
+msgstr "shell (sh)"
#. translators: command description
#: src/Zypper.cc:4386
#: src/commands/basecommand.cc:121
#, boost-format
msgid " Default: %1%"
-msgstr ""
+msgstr " Padrão: %1%"
#: src/commands/basecommand.cc:134
-#, fuzzy
msgid "Options:"
-msgstr "opcional"
+msgstr "Opções:"
#. translators: property name; short; used like "Name: value"
#. translators: Table column header
#: src/utils/flags/exceptions.cc:21
#, boost-format
msgid "The flag %1% is not known."
-msgstr ""
+msgstr "O indicador %1% não é conhecido."
#: src/utils/flags/exceptions.cc:27
msgid "The flag %1% is not compatible with argument %2% (%2)."
-msgstr ""
+msgstr "O indicador %1% não é compatÃvel com o argumento %2% (%2)."
#: src/utils/flags/exceptions.cc:33
-#, fuzzy, boost-format
+#, boost-format
msgid "The flag %1% requires a argument."
-msgstr "O nome do pacote fonte é um argumento necessário."
+msgstr "O indicador %1% requer um argumento."
#: src/utils/flags/exceptions.cc:39
#, boost-format
msgid "The flag %1% can only be used once."
-msgstr ""
+msgstr "O indicador %1% só pode ser usado uma vez."
#: src/utils/flags/flagtypes.cc:48
msgid "Out of range"
-msgstr ""
+msgstr "Fora do alcance"
#: src/utils/flags/flagtypes.cc:50
#, boost-format
msgid "Unknown error while assigning the value %1% to flag %2%."
-msgstr ""
+msgstr "Erro desconhecido ao atribuir o valor %1% ao indicador %2%."
#. For '-garbage' argument, with 'a', 'b', and 'e' as known options,
#. getopt_long reports 'a', 'b', and 'e' as known options.
search.h
info.h
Table.h
- locks.h
update.h
download.h
source-download.h
configtest.h
solve-commit.h
PackageArgs.h
- ps.h
SolverRequester.h
Summary.h
callbacks/keyring.h
callbacks/repo.h
callbacks/job.h
commands/commandhelpformatter.h
+ commands/conditions.h
commands/basecommand.h
commands/locks.h
commands/locks/add.h
+ commands/locks/clean.h
commands/locks/list.h
commands/locks/remove.h
+ commands/services.h
+ commands/services/common.h
+ commands/services/list.h
+ commands/services/refresh.h
+ commands/services/add.h
+ commands/services/modify.h
+ commands/services/remove.h
+ commands/repos.h
+ commands/repos/list.h
+ commands/repos/add.h
+ commands/repos/clean.h
+ commands/repos/remove.h
+ commands/repos/rename.h
+ commands/repos/modify.h
+ commands/repos/refresh.h
+ commands/reposerviceoptionsets.h
+ commands/ps.h
)
SET( zypper_SRCS
search.cc
info.cc
Table.cc
- locks.cc
update.cc
download.cc
source-download.cc
configtest.cc
solve-commit.cc
PackageArgs.cc
- ps.cc
RequestFeedback.cc
SolverRequester.cc
Summary.cc
callbacks/media.cc
commands/commandhelpformatter.cc
+ commands/conditions.cc
commands/basecommand.cc
commands/locks/add.cc
+ commands/locks/clean.cc
commands/locks/list.cc
commands/locks/remove.cc
+ commands/services/common.cc
+ commands/services/list.cc
+ commands/services/refresh.cc
+ commands/services/add.cc
+ commands/services/modify.cc
+ commands/services/remove.cc
+ commands/repos/list.cc
+ commands/repos/add.cc
+ commands/repos/clean.cc
+ commands/repos/remove.cc
+ commands/repos/rename.cc
+ commands/repos/modify.cc
+ commands/repos/refresh.cc
+ commands/reposerviceoptionsets.cc
+ commands/ps.cc
${zypper_HEADERS}
)
\*---------------------------------------------------------------------------*/
#include <map>
+#include <functional>
#include <zypp/base/NamedValue.h>
#include <zypp/base/Exception.h>
#include "Command.h"
#include "commands/locks.h"
+#include "commands/services.h"
+#include "commands/repos.h"
+#include "commands/ps.h"
using namespace zypp;
///////////////////////////////////////////////////////////////////
namespace
{
+
+ template<typename T>
+ ZypperBaseCommandPtr commandFactory ( const std::vector<std::string> &aliases_r )
+ {
+ return std::make_shared<T> ( aliases_r );
+ }
+
+ struct CommandFactory {
+ std::vector<std::string> aliases;
+ std::function<ZypperBaseCommandPtr ( const std::vector<std::string> & )> constructor;
+
+ ZypperBaseCommandPtr operator ()()
+ {
+ return constructor( aliases );
+ }
+
+ template <typename T>
+ constexpr static CommandFactory make ( const std::vector<std::string> &aliases_r )
+ {
+ return CommandFactory { aliases_r, commandFactory<T>};
+ }
+ };
+
//@TODO hack for now, this should be migrated to be part of Zypper class directly instead of a
//singleton
- static std::map< ZypperCommand::Command, ZypperBaseCommandPtr > &newStyleCommands ()
+ static std::map< ZypperCommand::Command, CommandFactory > &newStyleCommands ()
{
- static std::map< ZypperCommand::Command, ZypperBaseCommandPtr > table {
- { ZypperCommand::LIST_LOCKS_e, std::make_shared<ListLocksCmd>() }
+ static std::map< ZypperCommand::Command, CommandFactory> table {
+ { ZypperCommand::LIST_LOCKS_e, CommandFactory::make<ListLocksCmd>( { "locks", "ll", "lock-list" }) },
+ { ZypperCommand::ADD_LOCK_e, CommandFactory::make<AddLocksCmd>({ "addlock", "al", "lock-add", "la" }) },
+ { ZypperCommand::REMOVE_LOCK_e, CommandFactory::make<RemoveLocksCmd>({ "removelock", "rl", "lock-delete" , "ld" }) },
+ { ZypperCommand::CLEAN_LOCKS_e, CommandFactory::make<CleanLocksCmd> ({ "cleanlocks" , "cl", "lock-clean" }) },
+
+ { ZypperCommand::LIST_SERVICES_e, CommandFactory::make<ListServicesCmd>( { "services", "ls", "service-list", "sl" } ) },
+ { ZypperCommand::REFRESH_SERVICES_e, CommandFactory::make<RefreshServicesCmd>( { "refresh-services", "refs" } ) },
+ { ZypperCommand::MODIFY_SERVICE_e, CommandFactory::make<ModifyServiceCmd>( { "modifyservice", "ms" } ) }, //<<
+ { ZypperCommand::REMOVE_SERVICE_e, CommandFactory::make<RemoveServiceCmd>( { "removeservice", "rs", "service-delete", "sd" } ) },
+ { ZypperCommand::ADD_SERVICE_e, CommandFactory::make<AddServiceCmd>( { "addservice", "as", "service-add", "sa" } ) },
+
+ { ZypperCommand::LIST_REPOS_e, CommandFactory::make<ListReposCmd>( {"repos", "lr", "catalogs","ca"} ) },
+ { ZypperCommand::ADD_REPO_e, CommandFactory::make<AddRepoCmd>( { "addrepo", "ar" } ) },
+ { ZypperCommand::REMOVE_REPO_e, CommandFactory::make<RemoveRepoCmd>( { "removerepo", "rr" } ) },
+ { ZypperCommand::RENAME_REPO_e, CommandFactory::make<RenameRepoCmd>( { "renamerepo", "nr" } ) },
+ { ZypperCommand::MODIFY_REPO_e, CommandFactory::make<ModifyRepoCmd>( { "modifyrepo", "mr" } ) },
+ { ZypperCommand::REFRESH_e, CommandFactory::make<RefreshRepoCmd>( { "refresh", "ref" } ) },
+ { ZypperCommand::CLEAN_e, CommandFactory::make<CleanRepoCmd>( { "clean", "cc", "clean-cache", "you-clean-cache", "yc" } ) },
+
+ { ZypperCommand::PS_e, CommandFactory::make<PSCommand>( { "ps" }) }
};
return table;
}
- static NamedValue<ZypperCommand::Command> & table()
+ static NamedValue<ZypperCommand::Command> & cmdTable()
{
static NamedValue<ZypperCommand::Command> _table;
if ( _table.empty() )
_t( NONE_e ) | "NONE" | "none" | "";
_t( SUBCOMMAND_e) | "subcommand";
- _t( ADD_SERVICE_e ) | "addservice" | "as" | "service-add" | "sa";
- _t( REMOVE_SERVICE_e ) | "removeservice" | "rs" | "service-delete" | "sd";
- _t( MODIFY_SERVICE_e ) | "modifyservice" | "ms";
- _t( LIST_SERVICES_e ) | "services" | "ls" | "service-list" | "sl";
- _t( REFRESH_SERVICES_e ) | "refresh-services" | "refs";
+ //_t( ADD_SERVICE_e ) | "addservice" | "as" | "service-add" | "sa";
+ //_t( REMOVE_SERVICE_e ) | "removeservice" | "rs" | "service-delete" | "sd";
+ //_t( MODIFY_SERVICE_e ) | "modifyservice" | "ms";
+ //_t( LIST_SERVICES_e ) | "services" | "ls" | "service-list" | "sl";
+ //_t( REFRESH_SERVICES_e ) | "refresh-services" | "refs";
- _t( ADD_REPO_e ) | "addrepo" | "ar";
- _t( REMOVE_REPO_e ) | "removerepo" | "rr";
- _t( RENAME_REPO_e ) | "renamerepo" | "nr";
- _t( MODIFY_REPO_e ) | "modifyrepo" | "mr";
- _t( LIST_REPOS_e ) | "repos" | "lr" | "catalogs" | "ca";
- _t( REFRESH_e ) | "refresh" | "ref";
- _t( CLEAN_e ) | "clean" | "cc" | "clean-cache" | "you-clean-cache" | "yc";
+ //_t( ADD_REPO_e ) | "addrepo" | "ar";
+ //_t( REMOVE_REPO_e ) | "removerepo" | "rr";
+ //_t( RENAME_REPO_e ) | "renamerepo" | "nr";
+ //_t( MODIFY_REPO_e ) | "modifyrepo" | "mr";
+ //_t( LIST_REPOS_e ) | "repos" | "lr" | "catalogs" | "ca";
+ //_t( REFRESH_e ) | "refresh" | "ref";
+ //_t( CLEAN_e ) | "clean" | "cc" | "clean-cache" | "you-clean-cache" | "yc";
_t( INSTALL_e ) | "install" | "in";
_t( REMOVE_e ) | "remove" | "rm";
//_t( WHAT_REQUIRES_e ) | "what-requires" | "wr";
//_t( WHAT_CONFLICTS_e ) | "what-conflicts" | "wc";
- _t( ADD_LOCK_e ) | "addlock" | "al" | "lock-add" | "la";
- _t( REMOVE_LOCK_e ) | "removelock" | "rl" | "lock-delete" | "ld";
- //_t( LIST_LOCKS_e ) | "locks" | "ll" | "lock-list";
- _t( CLEAN_LOCKS_e ) | "cleanlocks" | "cl" | "lock-clean";
+ // _t( ADD_LOCK_e ) | "addlock" | "al" | "lock-add" | "la";
+ // _t( REMOVE_LOCK_e ) | "removelock" | "rl" | "lock-delete" | "ld";
+ // _t( LIST_LOCKS_e ) | "locks" | "ll" | "lock-list";
+ // _t( CLEAN_LOCKS_e ) | "cleanlocks" | "cl" | "lock-clean";
_t( TARGET_OS_e ) | "targetos" | "tos";
_t( VERSION_CMP_e ) | "versioncmp" | "vcmp";
_t( LICENSES_e ) | "licenses";
- _t( PS_e ) | "ps";
+ // _t( PS_e ) | "ps";
_t( DOWNLOAD_e ) | "download";
_t( SOURCE_DOWNLOAD_e ) | "source-download";
// patch the table to contain all new style commands
for ( const auto &cmd : newStyleCommands() ) {
auto entry = _table(cmd.first);
- for ( const std::string &alias : cmd.second->command())
+ for ( const std::string &alias : cmd.second.aliases)
entry | alias;
}
}
//set the command object if the passed enum represents a new style cmd
auto &newCmds = newStyleCommands();
if ( newCmds.find( _command ) != newCmds.end() ) {
- _newStyleCmdObj = newCmds[_command];
+ _newStyleCmdObj = newCmds[_command]();
}
}
ZypperCommand::Command ZypperCommand::parse( const std::string & strval_r ) const
{
ZypperCommand::Command cmd = SUBCOMMAND_e; // Exception if not true
- if ( ! table().getValue( strval_r, cmd ) )
+ if ( ! cmdTable().getValue( strval_r, cmd ) )
{
bool isSubcommand( const std::string & strval_r ); // in subcommand.cc
}
const std::string & ZypperCommand::asString() const
-{ return table().getName( _command ); }
+{ return cmdTable().getName( _command ); }
ZypperBaseCommandPtr ZypperCommand::commandObject() const
{
while ( pos != std::string::npos && arg.find_first_of( "(=" ) > pos )
{
repo = arg.substr( 0, pos );
+
if ( match_repo( zypper, repo ) )
{
hasRepo = true;
#include <unistd.h>
#include <readline/history.h>
-#include <sys/vfs.h>
-#include <sys/statvfs.h>
-#include <linux/magic.h>
#include <zypp/ZYppFactory.h>
#include <zypp/zypp_detail/ZYppReadOnlyHack.h>
#include "update.h"
#include "solve-commit.h"
#include "misc.h"
-#include "locks.h"
#include "search.h"
#include "info.h"
-#include "ps.h"
#include "download.h"
#include "source-download.h"
#include "configtest.h"
#include "commands/commandhelpformatter.h"
#include "commands/locks.h"
+#include "commands/services/common.h"
+#include "commands/services/refresh.h"
+#include "commands/conditions.h"
+#include "commands/reposerviceoptionsets.h"
+#include "commands/repos/refresh.h"
using namespace zypp;
bool sigExitOnce = true; // Flag to prevent nested calls to Zypper::immediateExit
} // namespace cli
///////////////////////////////////////////////////////////////////
+
ZYpp::Ptr God = NULL;
void Zypper::assertZYppPtrGod()
{
return mayuse;
}
- enum LegacyCLIMsgType {
- Local,
- Global,
- Ignored
- };
-
- inline std::string legacyCLIStr( const std::string & old_r, const std::string & new_r, LegacyCLIMsgType type_r )
- {
- switch (type_r) {
- case Local:
- case Global:
- return str::Format( type_r == Global
- ? _("Legacy commandline option %1% detected. Please use global option %2% instead.")
- : _("Legacy commandline option %1% detected. Please use %2% instead.") )
- % NEGATIVEString(dashdash(old_r))
- % POSITIVEString(dashdash(new_r));
- break;
- case Ignored:
- return str::Format(
- _("Legacy commandline option %1% detected. This option is ignored."))
- % NEGATIVEString(dashdash(old_r));
- break;
- }
- return std::string();
- }
-
- inline void legacyCLITranslate( parsed_opts & copts_r, const std::string & old_r, const std::string & new_r, Out::Verbosity verbosity_r = Out::NORMAL, LegacyCLIMsgType type = Local )
+ inline void legacyCLITranslate( parsed_opts & copts_r, const std::string & old_r, const std::string & new_r, Out::Verbosity verbosity_r = Out::NORMAL, LegacyCLIMsgType type = LegacyCLIMsgType::Local )
{
if ( copts_r.count( old_r ) )
{
case ZypperCommand::REMOVE_SERVICE_e:
case ZypperCommand::MODIFY_SERVICE_e:
#endif
- {
-
- if ( zypper.cOpts().count("dry-run") )
- return true;
-
- struct statfs fsinfo;
- memset( &fsinfo, 0, sizeof(struct statfs) );
-
- int err = 0;
- do {
- err = statfs( gopts_r.root_dir.c_str(), &fsinfo );
- } while ( err == -1 && errno == EINTR );
-
- if ( !err ) {
- if ( fsinfo.f_flags & ST_RDONLY ) {
-
- bool isTransactionalServer = ( fsinfo.f_type == BTRFS_SUPER_MAGIC && PathInfo( "/usr/sbin/transactional-update" ).isFile() );
-
- std::string msg;
- if ( isTransactionalServer && !gopts_r.changedRoot ) {
- msg = _("This is a transactional-server, please use transactional-update to update or modify the system.");
- } else {
- msg = _("The target filesystem is mounted as read-only. Please make sure the target filesystem is writeable.");
- }
- zypper.out().errorPar( msg );
- ERR << msg << endl;
- return false;
- }
- } else {
- WAR << "Checking if " << gopts_r.root_dir << " is mounted read only failed with errno : " << errno << std::endl;
+ {
+ std::string msg;
+ NeedsWritableRoot rt;
+ if ( rt.check( msg ) != ZYPPER_EXIT_OK ) {
+ zypper.out().errorPar( msg );
+ return false;
}
break;
}
int Zypper::defaultLoadSystem( LoadSystemFlags flags_r )
{
DBG << "FLAGS:" << flags_r << endl;
- if ( ! flags_r.testFlag( NO_POOL ) )
+
+ if ( ! flags_r.testFlag( NoPool ) )
{
init_target( *this );
if ( exitCode() != ZYPPER_EXIT_OK )
return exitCode();
- if ( ! flags_r.testFlag( NO_REPOS ) )
+ if ( ! flags_r.testFlag( NoRepos ) )
{
init_repos(*this);
if ( exitCode() != ZYPPER_EXIT_OK )
}
DtorReset _tmp( _gopts.disable_system_resolvables );
- if ( flags_r.testFlag( NO_TARGET ) )
+ if ( flags_r.testFlag( NoTarget ) )
{
_gopts.disable_system_resolvables = true;
}
if ( exitCode() != ZYPPER_EXIT_OK )
return exitCode();
- if ( ! ( flags_r & NO_POOL ) )
+ if ( ! ( flags_r & NoPool ) )
{
// have REPOS and TARGET
// compute status of PPP
ZypperBaseCommandPtr newStyleCmd = command().commandObject();
if ( newStyleCmd ) {
+ //reset the command to default
+ newStyleCmd->reset();
+
+ //get command help
_command_help = newStyleCmd->help();
MIL << "Found new style command << " << newStyleCmd->command().front() << endl;
// parse command options
try {
- //reset the command to default
- newStyleCmd->reset();
-
int nextArg = ZyppFlags::parseCLI( argc(), argv(), newStyleCmd->options(), optind );
MIL << "Parsed new style arguments" << endl;
break;
}
- case ZypperCommand::ADD_SERVICE_e:
- {
- static struct option service_add_options[] = {
- {"type", required_argument, 0, 't'},
- {"help", no_argument, 0, 'h'},
- ARG_SERVICE_PROP,
- {0, 0, 0, 0}
- };
#if 0
_(
// translators: the %s = "ris" (the only service type currently supported)
"-n, --name <name> Specify descriptive name for the service.\n"
)
#endif
- specific_options = service_add_options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("addservice (as) [OPTIONS] <URI> <ALIAS>")
- )
- .description(// translators: command description
- _("Add a repository index service to the system.")
- )
- .optionSectionCommandOptions()
- .option_SERVICE_PROP
- .legacyOptionSection()
- .option( "-t, --type <TYPE>", ( str::Format(_("The type of service is always autodetected. This option is ignored.") ) ).str() ) // FIXME: leagcy, actually autodetected but check libzypp
- ;
- break;
- }
-
- case ZypperCommand::REMOVE_SERVICE_e:
- {
- static struct option options[] = {
- {"help", no_argument, 0, 'h'},
- {"loose-auth", no_argument, 0, 0},
- {"loose-query", no_argument, 0, 0},
- {0, 0, 0, 0}
- };
- specific_options = options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("removeservice (rs) [OPTIONS] <ALIAS|#|URI>")
- )
- .description( // translators: command description
- _("Remove specified repository index service from the system.")
- )
- .optionSectionCommandOptions()
- .option( "--loose-auth", // translators: --loose-auth
- _("Ignore user authentication data in the URI.") )
- .option( "--loose-query", // translators: --loose-query
- _("Ignore query string in the URI.") )
- ;
#if 0
_command_help = _(
// TranslatorExplanation the %s = "yast2, rpm-md, plaindir"
" --loose-query Ignore query string in the URI.\n"
);
#endif
- break;
- }
- case ZypperCommand::MODIFY_SERVICE_e:
- {
- static struct option service_modify_options[] = {
- {"help", no_argument, 0, 'h'},
- ARG_SERVICE_PROP,
- /* LEGACY(ARG_SERVICE_PROP) prefers -f */ {"refresh", no_argument, 0, 'r'},
- /* LEGACY(ARG_SERVICE_PROP) prefers -F */ {"no-refresh", no_argument, 0, 'R'},
- ARG_REPO_SERVICE_COMMON_AGGREGATE,
- {"ar-to-enable", required_argument, 0, 'i'},
- {"ar-to-disable", required_argument, 0, 'I'},
- {"rr-to-enable", required_argument, 0, 'j'},
- {"rr-to-disable", required_argument, 0, 'J'},
- {"cl-to-enable", no_argument, 0, 'k'},
- {"cl-to-disable", no_argument, 0, 'K'},
- {0, 0, 0, 0}
- };
#if 0
_(
// translators: %s is "--all" and "--all"
"-t, --remote Apply changes to all remote services.\n"
"-m, --medium-type <type> Apply changes to services of specified type.\n"
)
-#endif
- specific_options = service_modify_options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("modifyservice (ms) <OPTIONS> <ALIAS|#|URI>")
- )
- .synopsis( str::Format( // translators: command synopsis; do not translate lowercase words
- _("modifyservice (ms) <OPTIONS> <%1%>") ) % "--all|--remote|--local|--medium-type"
- )
- .description( str::Format(// translators: command description
- _("Modify properties of services specified by alias, number, or URI, or by the '%1%' aggregate options.") ) % "--all, --remote, --local, --medium-type"
- )
- .optionSectionCommandOptions()
- .option_SERVICE_PROP
- .gap()
- .option( "-a, --all", _("Apply changes to all services.") )
- .option( "-l, --local", _("Apply changes to all local services.") )
- .option( "-t, --remote", _("Apply changes to all remote services.") )
- .option( "-m, --medium-type <TYPE>", _("Apply changes to services of specified type.") )
- .gap()
- .option( "-i, --ar-to-enable <ALIAS>", _("Add a RIS service repository to enable.") )
- .option( "-I, --ar-to-disable <ALIAS>", _("Add a RIS service repository to disable.") )
- .option( "-j, --rr-to-enable <ALIAS>", _("Remove a RIS service repository to enable.") )
- .option( "-J, --rr-to-disable <ALIAS>", _("Remove a RIS service repository to disable.") )
- .option( "-k, --cl-to-enable", _("Clear the list of RIS repositories to enable.") )
- .option( "-K, --cl-to-disable", _("Clear the list of RIS repositories to disable.") )
- // Legacy Options:
- .legacyOptionSection()
- .legacyOption( "-r", "-f" )
- .legacyOption( "-R", "-F" )
- ;
- break;
- }
- case ZypperCommand::LIST_SERVICES_e:
- {
- static struct option options[] =
- {
- {"help", no_argument, 0, 'h'},
- {"uri", no_argument, 0, 'u'},
- {"url", no_argument, 0, 0 },
- {"priority", no_argument, 0, 'p'},
- {"details", no_argument, 0, 'd'},
- {"with-repos", no_argument, 0, 'r'},
- {"show-enabled-only", no_argument, 0, 'E'},
- {"sort-by-uri", no_argument, 0, 'U'},
- {"sort-by-name", no_argument, 0, 'N'},
- {"sort-by-priority", no_argument, 0, 'P'},
- {0, 0, 0, 0}
- };
- specific_options = options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("services (ls) [OPTIONS]")
- )
- .description( // translators: command description
- _("List defined services.")
- )
- .optionSectionCommandOptions()
- .option( "-u, --uri", // translators: -u, --uri
- _("Show also base URI of repositories.") )
- .option( "-p, --priority", // translators: -p, --priority
- _("Show also repository priority.") )
- .option( "-d, --details", // translators: -d, --details
- _("Show more information like URI, priority, type.") )
- .option( "-r, --with-repos", // translators: -r, --with-repos
- _("Show also repositories belonging to the services.") )
- .option( "-E, --show-enabled-only", // translators: -E, --show-enabled-only
- _("Show enabled repos only.") )
- .option( "-P, --sort-by-priority", // translators: -P, --sort-by-priority
- _("Sort the list by repository priority.") )
- .option( "-U, --sort-by-uri", // translators: -U, --sort-by-uri
- _("Sort the list by URI.") )
- .option( "-N, --sort-by-name", // translators: -N, --sort-by-name
- _("Sort the list by name.") )
- ;
-#if 0
+ ZypperCommand::LIST_SERVICES_e:
_command_help = _(
"services (ls) [OPTIONS]\n"
"\n"
"-U, --sort-by-uri Sort the list by URI.\n"
"-N, --sort-by-name Sort the list by name.\n"
);
-#endif
- break;
- }
- case ZypperCommand::REFRESH_SERVICES_e:
- {
- static struct option options[] = {
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, 'h'},
- {"with-repos", no_argument, 0, 'r'},
- {"restore-status", no_argument, 0, 'R'},
- {0, 0, 0, 0}
- };
- specific_options = options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("refresh-services (refs) [OPTIONS]")
- )
- .description( // translators: command description
- _("Refresh defined repository index services.")
- )
- .optionSectionCommandOptions()
- .option( "-f, --force", // translators: -f, --force
- _("Force a complete refresh.") )
- .option( "-r, --with-repos", // translators: -r, --with-repos
- _("Refresh also the service repositories.") )
- .option( "-R, --restore-status", // translators: -R, --restore-status
- _("Also restore service repositories enabled/disabled state.") )
- ;
-#if 0
+ //ZypperCommand::REFRESH_SERVICES_e
_command_help = _(
"refresh-services (refs) [OPTIONS]\n"
"\n"
"-R, --restore-status Also restore service repositories enabled/disabled state.\n"
);
#endif
- break;
- }
- case ZypperCommand::ADD_REPO_e:
- {
- static struct option service_add_options[] = {
- {"type", required_argument, 0, 't'},
- {"repo", required_argument, 0, 'r'}, // :( conflicted with '-r --refresh', so ARG_REPO_PROP now uses -f/F
- {"help", no_argument, 0, 'h'},
- {"check", no_argument, 0, 'c'},
- {"no-check", no_argument, 0, 'C'},
- ARG_REPO_PROP,
- {0, 0, 0, 0}
- };
#if 0
_(
// translators: the %s = "yast2, rpm-md, plaindir"
"-f, --refresh Enable autorefresh of the repository.\n"
)
#endif
- specific_options = service_add_options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("addrepo (ar) [OPTIONS] <URI> <ALIAS>")
- )
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("addrepo (ar) [OPTIONS] <FILE.repo>")
- )
- .description(// translators: command description
- _("Add a repository to the system. The repository can be specified by its URI or can be read from specified .repo file (even remote).")
- )
- .optionSectionCommandOptions()
- .option( "-r, --repo <FILE.repo>", _("Just another means to specify a .repo file to read.") )
- .option( "-c, --check", _("Probe URI.") )
- .option( "-C, --no-check", _("Don't probe URI, probe later during refresh.") )
- .gap()
- .option_REPO_PROP
- .legacyOptionSection()
- .option( "-t, --type <TYPE>", str::Format(_("The repository type is always autodetected. This option is ignored.") ) )
- ;
- break;
- }
- case ZypperCommand::LIST_REPOS_e:
- {
- static struct option service_list_options[] = {
- {"export", required_argument, 0, 'e'},
- {"alias", no_argument, 0, 'a'},
- {"name", no_argument, 0, 'n'},
- {"refresh", no_argument, 0, 'r'},
- {"uri", no_argument, 0, 'u'},
- {"url", no_argument, 0, 0 },
- {"priority", no_argument, 0, 'p'},
- {"details", no_argument, 0, 'd'},
- {"show-enabled-only", no_argument, 0, 'E'},
- {"sort-by-priority", no_argument, 0, 'P'},
- {"sort-by-uri", no_argument, 0, 'U'},
- {"sort-by-alias", no_argument, 0, 'A'},
- {"sort-by-name", no_argument, 0, 'N'},
- {"service", no_argument, 0, 's'},
- {"help", no_argument, 0, 'h'},
- {0, 0, 0, 0}
- };
- specific_options = service_list_options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("repos (lr) [OPTIONS] [REPO] ...")
- )
- .description( // translators: command description
- _("List all defined repositories.")
- )
- .optionSectionCommandOptions()
- .option( "-e, --export <FILE.repo>", // translators: -e, --export <FILE.repo>
- _("Export all defined repositories as a single local .repo file.") )
- .option( "-a, --alias", // translators: -a, --alias
- _("Show also repository alias.") )
- .option( "-n, --name", // translators: -n, --name
- _("Show also repository name.") )
- .option( "-u, --uri", // translators: -u, --uri
- _("Show also base URI of repositories.") )
- .option( "-p, --priority", // translators: -p, --priority
- _("Show also repository priority.") )
- .option( "-r, --refresh", // translators: -r, --refresh
- _("Show also the autorefresh flag.") )
- .option( "-d, --details", // translators: -d, --details
- _("Show more information like URI, priority, type.") )
- .option( "-s, --service", // translators: -s, --service
- _("Show also alias of parent service.") )
- .option( "-E, --show-enabled-only", // translators: -E, --show-enabled-only
- _("Show enabled repos only.") )
- .option( "-U, --sort-by-uri", // translators: -U, --sort-by-uri
- _("Sort the list by URI.") )
- .option( "-P, --sort-by-priority", // translators: -P, --sort-by-priority
- _("Sort the list by repository priority.") )
- .option( "-A, --sort-by-alias", // translators: -A, --sort-by-alias
- _("Sort the list by alias.") )
- .option( "-N, --sort-by-name", // translators: -N, --sort-by-name
- _("Sort the list by name.") )
- ;
#if 0
_command_help = _(
"repos (lr) [OPTIONS] [repo] ...\n"
"-N, --sort-by-name Sort the list by name.\n"
);
#endif
- break;
- }
- case ZypperCommand::REMOVE_REPO_e:
- {
- static struct option service_delete_options[] = {
- {"help", no_argument, 0, 'h'},
- {"loose-auth", no_argument, 0, 0},
- {"loose-query", no_argument, 0, 0},
- ARG_REPO_SERVICE_COMMON_AGGREGATE,
- {0, 0, 0, 0}
- };
- specific_options = service_delete_options;
#if 0
- _command_help = ( CommandHelpFormater() << _(
- "removerepo (rr) [OPTIONS] <alias|#|URI>\n"
- "\n"
- "Remove repository specified by alias, number or URI.\n"
- "\n"
- " Command options:\n"
- " --loose-auth Ignore user authentication data in the URI.\n"
- " --loose-query Ignore query string in the URI.\n"
- ))
+ _command_help = ( CommandHelpFormater() << _(
+ "removerepo (rr) [OPTIONS] <alias|#|URI>\n"
+ "\n"
+ "Remove repository specified by alias, number or URI.\n"
+ "\n"
+ " Command options:\n"
+ " --loose-auth Ignore user authentication data in the URI.\n"
+ " --loose-query Ignore query string in the URI.\n"
+ ))
#endif
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("removerepo (rr) [OPTIONS] <ALIAS|#|URI>")
- )
- .description( // translators: command description
- _("Remove repository specified by alias, number or URI.")
- )
- .optionSectionCommandOptions()
- .option( "--loose-auth", // translators: --loose-auth
- _("Ignore user authentication data in the URI.") )
- .option( "--loose-query", // translators: --loose-query
- _("Ignore query string in the URI.") )
- .gap()
- .option_REPO_AGGREGATES;
- break;
- }
- case ZypperCommand::RENAME_REPO_e:
- {
- static struct option service_rename_options[] = {
- {"help", no_argument, 0, 'h'},
- {0, 0, 0, 0}
- };
- specific_options = service_rename_options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("renamerepo (nr) [OPTIONS] <ALIAS|#|URI> <NEW-ALIAS>")
- )
- .description( // translators: command description
- _("Assign new alias to the repository specified by alias, number or URI.")
- )
- .noOptionSection()
- ;
#if 0
_command_help = _(
"renamerepo (nr) [OPTIONS] <alias|#|URI> <new-alias>\n"
"This command has no additional options.\n"
);
#endif
- break;
- }
- case ZypperCommand::MODIFY_REPO_e:
- {
- static struct option service_modify_options[] = {
- {"help", no_argument, 0, 'h'},
- ARG_REPO_PROP,
- /* LEGACY(ARG_REPO_PROP) prefers -f */ {"refresh", no_argument, 0, 'r'},
- /* LEGACY(ARG_REPO_PROP) prefers -F */ {"no-refresh", no_argument, 0, 'R'},
- ARG_REPO_SERVICE_COMMON_AGGREGATE,
- {0, 0, 0, 0}
- };
#if 0
_(
// translators: %s is "--all|--remote|--local|--medium-type"
"-m, --medium-type <type> Apply changes to repositories of specified type.\n"
)
#endif
- specific_options = service_modify_options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("modifyrepo (mr) <OPTIONS> <ALIAS|#|URI>")
- )
- .synopsis( str::Format( // translators: command synopsis; do not translate lowercase words
- _("modifyrepo (mr) <OPTIONS> <%1%>") ) % "--all|--remote|--local|--medium-type"
- )
- .description( str::Format( // translators: command description
- _("Modify properties of repositories specified by alias, number, or URI, or by the '%1%' aggregate options.") ) % "--all, --remote, --local, --medium-type"
- )
- .optionSectionCommandOptions()
- .option_REPO_PROP
- .gap()
- .option_REPO_AGGREGATES
- // Legacy Options:
- .legacyOptionSection()
- .legacyOption( "-r", "-f" )
- .legacyOption( "-R", "-F" )
- ;
- break;
- }
- case ZypperCommand::REFRESH_e:
- {
- static struct option refresh_options[] = {
- {"force", no_argument, 0, 'f'},
- {"force-build", no_argument, 0, 'b'},
- {"force-download", no_argument, 0, 'd'},
- {"build-only", no_argument, 0, 'B'},
- {"download-only", no_argument, 0, 'D'},
- {"repo", required_argument, 0, 'r'},
- {"services", no_argument, 0, 's'},
- {"help", no_argument, 0, 'h'},
- {0, 0, 0, 0}
- };
- specific_options = refresh_options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("refresh (ref) [ALIAS|#|URI] ...")
- )
- .description( // translators: command description
- _("Refresh repositories specified by their alias, number or URI. If none are specified, all enabled repositories will be refreshed.")
- )
- .optionSectionCommandOptions()
- .option( "-f, --force", // translators: -f, --force
- _("Force a complete refresh.") )
- .option( "-b, --force-build", // translators: -b, --force-build
- _("Force rebuild of the database.") )
- .option( "-d, --force-download", // translators: -d, --force-download
- _("Force download of raw metadata.") )
- .option( "-B, --build-only", // translators: -B, --build-only
- _("Only build the database, don't download metadata.") )
- .option( "-D, --download-only", // translators: -D, --download-only
- _("Only download raw metadata, don't build the database.") )
- .option( "-r, --repo <ALIAS|#|URI>", // translators: -r, --repo <ALIAS|#|URI>
- _("Refresh only specified repositories.") )
- .option( "-s, --services", // translators: -s, --services
- _("Refresh also services before refreshing repos.") )
- ;
#if 0
_command_help = _(
"refresh (ref) [alias|#|URI] ...\n"
"-s, --services Refresh also services before refreshing repos.\n"
);
#endif
- break;
- }
-
- case ZypperCommand::CLEAN_e:
- {
- static struct option service_list_options[] = {
- {"help", no_argument, 0, 'h'},
- {"repo", required_argument, 0, 'r'},
- {"metadata", no_argument, 0, 'm'},
- {"raw-metadata", no_argument, 0, 'M'},
- {"all", no_argument, 0, 'a'},
- {0, 0, 0, 0}
- };
- specific_options = service_list_options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("clean (cc) [ALIAS|#|URI] ...")
- )
- .description( // translators: command description
- _("Clean local caches.")
- )
- .optionSectionCommandOptions()
- .option( "-r, --repo <ALIAS|#|URI>", // translators: -r, --repo <ALIAS|#|URI>
- _("Clean only specified repositories.") )
- .option( "-m, --metadata", // translators: -m, --metadata
- _("Clean metadata cache.") )
- .option( "-M, --raw-metadata", // translators: -M, --raw-metadata
- _("Clean raw metadata cache.") )
- .option( "-a, --all", // translators: -a, --all
- _("Clean both metadata and package caches.") )
- ;
#if 0
_command_help = _(
"clean (cc) [alias|#|URI] ...\n"
"-a, --all Clean both metadata and package caches.\n"
);
#endif
- break;
- }
case ZypperCommand::LIST_UPDATES_e:
{
break;
}
- case ZypperCommand::ADD_LOCK_e:
+ case ZypperCommand::TARGET_OS_e:
{
static struct option options[] =
{
- {"type", required_argument, 0, 't'},
- {"repo", required_argument, 0, 'r'},
- // rug compatibility (although rug does not seem to support this)
- {"catalog", required_argument, 0, 'c'},
- {"help", no_argument, 0, 'h'},
+ {"help", no_argument, 0, 'h'},
+ {"label", no_argument, 0, 'l'},
{0, 0, 0, 0}
};
specific_options = options;
_command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate the command 'name (abbreviations)' or '-option' names
- _("addlock (al) [OPTIONS] <PACKAGENAME> ...")
+ .synopsis( // translators: command synopsis; do not translate lowercase words
+ _("targetos (tos) [OPTIONS]")
)
.description( // translators: command description
- _("Add a package lock. Specify packages to lock by exact name or by a glob pattern using '*' and '?' wildcard characters.")
+ _("Show various information about the target operating system. By default, an ID string is shown.")
)
.optionSectionCommandOptions()
- .option( "-r, --repo <ALIAS|#|URI>", // translators: -r, --repo <ALIAS|#|URI>
- _("Restrict the lock to the specified repository.") )
- .option( "-t, --type <TYPE>", // translators: -t, --type <TYPE>
- str::Format(_("Type of package (%1%).") ) % "package, patch, pattern, product" )
- // NOTE: Original help text had a ' Default: %s", "package" appended.
+ .option( "-l, --label", // translators: -l, --label
+ _("Show the operating system label.") )
;
+#if 0
+ _command_help = _(
+ "targetos (tos) [OPTIONS]\n"
+ "\n"
+ "Show various information about the target operating system.\n"
+ "By default, an ID string is shown.\n"
+ "\n"
+ " Command options:\n"
+ "-l, --label Show the operating system label.\n"
+ );
+#endif
break;
}
- case ZypperCommand::REMOVE_LOCK_e:
+ case ZypperCommand::VERSION_CMP_e:
{
static struct option options[] =
{
- {"type", required_argument, 0, 't'},
- {"repo", required_argument, 0, 'r'},
- // rug compatibility (although rug does not seem to support this)
- {"catalog", required_argument, 0, 'c'},
{"help", no_argument, 0, 'h'},
+ {"match", no_argument, 0, 'm'},
{0, 0, 0, 0}
};
specific_options = options;
_command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate the command 'name (abbreviations)' or '-option' names
- _("removelock (rl) [OPTIONS] <LOCK-NUMBER|PACKAGENAME> ...")
+ .synopsis( // translators: command synopsis; do not translate lowercase words
+ _("versioncmp (vcmp) <VERSION1> <VERSION2>")
)
- .description( // translators: command description; %1% is acoomand like 'zypper locks'
- str::Format(_("Remove a package lock. Specify the lock to remove by its number obtained with '%1%' or by package name.") ) % "zypper locks"
+ .description( // translators: command description
+ _("Compare the versions supplied as arguments.")
)
.optionSectionCommandOptions()
- .option( "-r, --repo <ALIAS|#|URI>", // translators: -r, --repo <ALIAS|#|URI>
- _("Remove only locks with specified repository.") )
- .option( "-t, --type <TYPE>", // translators: -t, --type <TYPE>
- str::Format(_("Type of package (%1%).") ) % "package, patch, pattern, product" )
- // NOTE: Original help text had a ' Default: %s", "package" appended.
+ .option( "-m, --match", // translators: -m, --match
+ _("Takes missing release number as any release.") )
;
- break;
- }
-
- case ZypperCommand::CLEAN_LOCKS_e:
- {
- static struct option options[] =
- {
- {"help", no_argument, 0, 'h'},
- {"only-duplicates", no_argument, 0, 'd' },
- {"only-empty", no_argument, 0, 'e' },
- {0, 0, 0, 0}
- };
- specific_options = options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate the command 'name (abbreviations)' or '-option' names
- _("cleanlocks (cl)")
- )
- .description( // translators: command description
- _("Remove useless locks.")
- )
- .optionSectionCommandOptions()
- .option( "-d, --only-duplicates", // translators: -d, --only-duplicates
- _("Clean only duplicate locks.") )
- .option( "-e, --only-empty", // translators: -e, --only-empty
- _("Clean only locks which doesn't lock anything.") )
- ;
- break;
- }
-
- case ZypperCommand::TARGET_OS_e:
- {
- static struct option options[] =
- {
- {"help", no_argument, 0, 'h'},
- {"label", no_argument, 0, 'l'},
- {0, 0, 0, 0}
- };
- specific_options = options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("targetos (tos) [OPTIONS]")
- )
- .description( // translators: command description
- _("Show various information about the target operating system. By default, an ID string is shown.")
- )
- .optionSectionCommandOptions()
- .option( "-l, --label", // translators: -l, --label
- _("Show the operating system label.") )
- ;
-#if 0
- _command_help = _(
- "targetos (tos) [OPTIONS]\n"
- "\n"
- "Show various information about the target operating system.\n"
- "By default, an ID string is shown.\n"
- "\n"
- " Command options:\n"
- "-l, --label Show the operating system label.\n"
- );
-#endif
- break;
- }
-
- case ZypperCommand::VERSION_CMP_e:
- {
- static struct option options[] =
- {
- {"help", no_argument, 0, 'h'},
- {"match", no_argument, 0, 'm'},
- {0, 0, 0, 0}
- };
- specific_options = options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate lowercase words
- _("versioncmp (vcmp) <VERSION1> <VERSION2>")
- )
- .description( // translators: command description
- _("Compare the versions supplied as arguments.")
- )
- .optionSectionCommandOptions()
- .option( "-m, --match", // translators: -m, --match
- _("Takes missing release number as any release.") )
- ;
-#if 0
- _command_help = _(
- "versioncmp (vcmp) <version1> <version2>\n"
- "\n"
- "Compare the versions supplied as arguments.\n"
- "\n"
- " Command options:\n"
- "-m, --match Takes missing release number as any release.\n"
- );
-#endif
+#if 0
+ _command_help = _(
+ "versioncmp (vcmp) <version1> <version2>\n"
+ "\n"
+ "Compare the versions supplied as arguments.\n"
+ "\n"
+ " Command options:\n"
+ "-m, --match Takes missing release number as any release.\n"
+ );
+#endif
break;
}
break;
}
-
- case ZypperCommand::PS_e:
- {
- shared_ptr<PsOptions> myOpts( new PsOptions() );
- _commandOptions = myOpts;
- static struct option options[] =
- {
- {"help", no_argument, 0, 'h'},
- {"short", no_argument, 0, 's'},
- {"print", required_argument, 0, 0 },
- {"debugFile", required_argument, 0, 'd' },
- {0, 0, 0, 0}
- };
- specific_options = options;
- _command_help = CommandHelpFormater()
- .synopsis( // translators: command synopsis; do not translate the command 'name (abbreviations)' or '-option' names
- _("ps [OPTIONS]")
- )
- .description( // translators: command description
- _("List running processes which might still use files and libraries deleted by recent upgrades.")
- )
- .optionSectionCommandOptions()
- .option( "-s, --short", // translators: -s, --short
- _("Create a short table not showing the deleted files. Given twice, show only processes which are associated with a system service. Given three times, list the associated system service names only.") )
- .option( "--print <FORMAT>", // translators: --print <FORMAT>
- _("For each associated system service print <FORMAT> on the standard output, followed by a newline. Any '%s' directive in <FORMAT> is replaced by the system service name.") )
- .option("-d, --debugFile <PATH>", // translators: -d, --debugFile <PATH>
- _("Write debug output to file <PATH>."))
- ;
- break;
- }
-
-
case ZypperCommand::DOWNLOAD_e:
{
shared_ptr<DownloadOptions> myOpts( new DownloadOptions() );
}
default:
- {
- if ( runningHelp() )
- break;
-
- ERR << "Unknown or unexpected command" << endl;
- out().error(_("Unexpected program flow."));
- report_a_bug( out() );
- }
- }
-
- // no need to parse command options if we already know we just want help
- if ( runningHelp() )
- return;
-
- // parse command options
- _copts = parse_options( argc(), argv(), specific_options );
- if ( _copts.count("_unknown") || _copts.count("_missing_arg") )
- {
- setExitCode( ZYPPER_EXIT_ERR_SYNTAX );
- ERR << "Unknown option or missing argument, returning." << endl;
- return;
- }
-
- // Leagcy cli translations (mostly from rug to zypper)
- legacyCLITranslate( _copts, "agree-to-third-party-licenses", "auto-agree-with-licenses" );
- legacyCLITranslate( _copts, "sort-by-catalog", "sort-by-repo" );
- legacyCLITranslate( _copts, "uninstalled-only", "not-installed-only", Out::HIGH ); // bsc#972997: Prefer --not-installed-only over misleading --uninstalled-only
-
- if ( command().toEnum() == ZypperCommand::ADD_REPO_e || command().toEnum() == ZypperCommand::ADD_SERVICE_e ) {
- legacyCLITranslate( _copts, "type", "", Out::NORMAL, LegacyCLIMsgType::Ignored);
- }
-
- // bsc#957862: pkg/apt/yum user convenience: no-confirm ==> --non-interactive
- if ( _copts.count("no-confirm") )
- {
- if ( ! _gopts.non_interactive )
- {
- out().info(_("Entering non-interactive mode."), Out::HIGH );
- MIL << "Entering non-interactive mode" << endl;
- _gopts.non_interactive = true;
- }
- }
-
- ::copts = _copts;
- MIL << "Done parsing options." << endl;
-
- // treat --help command option like global --help option from now on
- // i.e. when used together with command to print command specific help
- setRunningHelp( runningHelp() || copts.count("help") );
-
- if ( optind < argc() )
- {
- std::ostringstream s;
- s << _("Non-option program arguments: ");
- while ( optind < argc() )
- {
- std::string argument = argv()[optind++];
- s << "'" << argument << "' ";
- _arguments.push_back( argument );
- }
- out().info( s.str(), Out::HIGH );
- }
-
- MIL << "Done " << endl;
-}
-
-/// process one command from the OS shell or the zypper shell
-void Zypper::doCommand()
-{
- // help check is common to all commands
- if ( runningHelp() )
- {
- out().info( _command_help, Out::QUIET );
- if ( command() == ZypperCommand::SEARCH )
- SLE15_SearchPackagesHintHack( *this );
- return;
- }
-
- // === ZYpp lock ===
- switch ( command().toEnum() )
- {
- case ZypperCommand::PS_e:
- case ZypperCommand::SUBCOMMAND_e:
- // bnc#703598: Quick fix as few commands do not need a zypp lock
- break;
-
- default:
- if ( _gopts.changedRoot && _gopts.root_dir != "/" )
- {
- // bnc#575096: Quick fix
- ::setenv( "ZYPP_LOCKFILE_ROOT", _gopts.root_dir.c_str(), 0 );
- }
- {
- const char *roh = getenv( "ZYPP_READONLY_HACK" );
- if ( roh != NULL && roh[0] == '1' )
- zypp_readonly_hack::IWantIt ();
-
- else if ( command() == ZypperCommand::LIST_REPOS
- || command() == ZypperCommand::LIST_SERVICES
- || command() == ZypperCommand::VERSION_CMP
- || command() == ZypperCommand::TARGET_OS )
- zypp_readonly_hack::IWantIt (); // #247001, #302152
- }
- assertZYppPtrGod();
- }
- // === execute command ===
-
- if ( !checkRequiredCapabilities( *this, _gopts ) ) {
- setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
- return;
- }
-
- MIL << "Going to process command " << command() << endl;
-
- //handle new style commands
- ZypperBaseCommandPtr newStyleCmd = command().commandObject();
- if ( newStyleCmd ) {
- int exitCode = defaultLoadSystem( newStyleCmd->needSystemSetup() );
- if ( ZYPPER_EXIT_OK != exitCode ) {
- setExitCode( exitCode );
- return;
- }
-
- setExitCode( newStyleCmd->run(*this, _arguments) );
- return;
- }
-
- ResObject::Kind kind;
- switch( command().toEnum() )
- {
-
- // --------------------------( moo )----------------------------------------
-
- case ZypperCommand::MOO_e:
- {
- // TranslatorExplanation this is a hedgehog, paint another animal, if you want
- out().info(_(" \\\\\\\\\\\n \\\\\\\\\\\\\\__o\n__\\\\\\\\\\\\\\'/_"));
- break;
- }
-
- // --------------------------( service list )-------------------------------
-
- case ZypperCommand::LIST_SERVICES_e:
- {
- initRepoManager();
- if ( copts.count( "with-repos" ) )
- checkIfToRefreshPluginServices( *this );
- list_services( *this );
-
- break;
- }
-
- // --------------------------( service refresh )-----------------------------
-
- case ZypperCommand::REFRESH_SERVICES_e:
- {
- // check root user
- if ( geteuid() != 0 && !globalOpts().changedRoot )
- {
- out().error(_("Root privileges are required for refreshing services.") );
- setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
- return;
- }
-
- // needed to be able to retrieve target distribution
- init_target(*this);
- _gopts.rm_options.servicesTargetDistro =
- God->target()->targetDistribution();
-
- initRepoManager();
-
- refresh_services( *this );
-
- break;
- }
-
- // --------------------------( add service )---------------------------------
-
- case ZypperCommand::ADD_SERVICE_e:
- {
- // check root user
- if ( geteuid() != 0 && !globalOpts().changedRoot )
- {
- out().error(_("Root privileges are required for modifying system services.") );
- setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
- return;
- }
-
- // too many arguments
- if ( _arguments.size() > 2 )
- {
- report_too_many_arguments( _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
-
- // missing arguments
- if ( _arguments.size() < 2 )
- {
- report_required_arg_missing( out(), _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
-
- Url url = make_url( _arguments[0] );
- if ( !url.isValid() )
- {
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
-
- initRepoManager();
- // force specific repository type.
- std::string type = copts.count("type") ? copts["type"].front() : "";
-
- // check for valid service type
- bool isservice = false;
- if ( type.empty() )
- {
- // zypper does not access net when adding repos/services, thus for zypper
- // the URI is always service unless --type is explicitely specified.
- isservice = true;
- }
- else
- {
- try
- {
- repo::ServiceType stype(type);
- isservice = true;
- }
- catch ( const repo::RepoUnknownTypeException & e )
- {}
- }
-
- if ( isservice )
- add_service_by_url( *this, url, _arguments[1] );
- else
- {
- try
- {
- add_repo_by_url( *this, url, _arguments[1]);
- }
- catch ( const repo::RepoUnknownTypeException & e )
- {
- ZYPP_CAUGHT( e );
- out().error(
- str::form(_("'%s' is not a valid service type."), type.c_str()),
- str::form(
- _("See '%s' or '%s' to get a list of known service types."),
- "zypper help addservice", "man zypper"));
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- }
- }
-
- break;
- }
-
- case ZypperCommand::MODIFY_SERVICE_e:
- {
- // check root user
- if ( geteuid() != 0 && !globalOpts().changedRoot )
- {
- out().error(_("Root privileges are required for modifying system services.") );
- setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
- return;
- }
-
- bool non_alias = copts.count("all") || copts.count("local") || copts.count("remote") || copts.count("medium-type");
-
- if ( _arguments.size() < 1 && !non_alias )
- {
- // translators: aggregate option is e.g. "--all". This message will be
- // followed by ms command help text which will explain it
- out().error(_("Alias or an aggregate option is required."));
- ERR << "No alias argument given." << endl;
- out().info( _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
- // too many arguments
- if ( _arguments.size() > 1 || ( _arguments.size() > 0 && non_alias ) )
- {
- report_too_many_arguments( _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
-
- initRepoManager();
-
- if ( non_alias )
- {
- modify_services_by_option( *this );
- }
- else
- {
- repo::RepoInfoBase_Ptr srv;
- if ( match_service( *this, _arguments[0], srv ) )
- {
- if ( dynamic_pointer_cast<ServiceInfo>(srv) )
- modify_service( *this, srv->alias() );
- else
- modify_repo( *this, srv->alias() );
- }
- else
- {
- out().error( str::Format(_("Service '%s' not found.")) % _arguments[0] );
- ERR << "Service " << _arguments[0] << " not found" << endl;
- }
- }
-
- break;
- }
-
- // --------------------------( repo list )----------------------------------
-
- case ZypperCommand::LIST_REPOS_e:
- {
- initRepoManager();
- checkIfToRefreshPluginServices( *this );
- list_repos( *this );
-
- break;
- }
-
- // --------------------------( addrepo )------------------------------------
-
- case ZypperCommand::ADD_REPO_e:
- {
- // check root user
- if ( geteuid() != 0 && !globalOpts().changedRoot )
- {
- out().error( _("Root privileges are required for modifying system repositories.") );
- setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
- return;
- }
-
- // too many arguments
- if ( _arguments.size() > 2 )
- {
- report_too_many_arguments( _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
-
- try
- {
- // add repository specified in .repo file
- if ( copts.count("repo") )
- {
- add_repo_from_file( *this,copts["repo"].front() );
- return;
- }
-
- switch ( _arguments.size() )
- {
- // display help message if insufficient info was given
- case 0:
- out().error(_("Too few arguments."));
- ERR << "Too few arguments." << endl;
- out().info( _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- case 1:
- if( !isRepoFile( _arguments[0] ) )
- {
- out().error(_("If only one argument is used, it must be a URI pointing to a .repo file."));
- ERR << "Not a repo file." << endl;
- out().info( _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
- else
- {
- initRepoManager();
- add_repo_from_file( *this,_arguments[0] );
- break;
- }
- case 2:
- Url url;
- if ( _arguments[0].find("obs") == 0 )
- url = make_obs_url( _arguments[0], config().obs_baseUrl, config().obs_platform );
- else
- url = make_url( _arguments[0] );
- if ( !url.isValid() )
- {
- setExitCode(ZYPPER_EXIT_ERR_INVALID_ARGS);
- return;
- }
-
- if ( copts.count("check") )
- {
- if ( !copts.count("no-check") )
- _gopts.rm_options.probe = true;
- else
- out().warning(str::form(
- _("Cannot use %s together with %s. Using the %s setting."),
- "--check", "--no-check", "zypp.conf")
- ,Out::QUIET );
- }
- else if ( copts.count("no-check") )
- _gopts.rm_options.probe = false;
-
- initRepoManager();
-
- // load gpg keys
- init_target( *this );
-
- add_repo_by_url( *this, url, _arguments[1]/*alias*/ );
- return;
- }
- }
- catch ( const repo::RepoUnknownTypeException & e )
- {
- ZYPP_CAUGHT( e );
- out().error( e, _("Specified type is not a valid repository type:"),
- str::form( _("See '%s' or '%s' to get a list of known repository types."),
- "zypper help addrepo", "man zypper" ) );
- setExitCode(ZYPPER_EXIT_ERR_INVALID_ARGS);
- }
-
- break;
- }
-
- // --------------------------( delete repo )--------------------------------
-
- case ZypperCommand::REMOVE_SERVICE_e:
- case ZypperCommand::REMOVE_REPO_e:
- {
- // check root user
- if (geteuid() != 0 && !globalOpts().changedRoot)
- {
- out().error(
- command() == ZypperCommand::REMOVE_REPO ?
- _("Root privileges are required for modifying system repositories.") :
- _("Root privileges are required for modifying system services.") );
- setExitCode(ZYPPER_EXIT_ERR_PRIVILEGES);
- return;
- }
-
- if (command() == ZypperCommand::REMOVE_REPO)
- {
- bool aggregate = copts.count("all") || copts.count("local") || copts.count("remote") || copts.count("medium-type");
-
- if ( _arguments.size() < 1 && !aggregate )
- {
- report_alias_or_aggregate_required ( out(), _command_help );
- ERR << "No alias argument given." << endl;
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
-
- // too many arguments
- if ( _arguments.size() && aggregate )
- {
- report_too_many_arguments( out(), _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
-
- initRepoManager();
- if ( aggregate )
- {
- remove_repos_by_option( *this );
- }
- else
- {
- // must store repository before remove to ensure correct match number
- std::set<RepoInfo,RepoInfoAliasComparator> repo_to_remove;
- for_(it, _arguments.begin(), _arguments.end())
- {
- RepoInfo repo;
- if (match_repo(*this,*it,&repo))
- {
- repo_to_remove.insert(repo);
- }
- else
- {
- MIL << "Repository not found by given alias, number or URI." << endl;
- // translators: %s is the supplied command line argument which
- // for which no repository counterpart was found
- out().error( str::Format(_("Repository '%s' not found by alias, number or URI.")) % *it );
- }
- }
-
- for_(it, repo_to_remove.begin(), repo_to_remove.end())
- remove_repo(*this,*it);
- }
- }
- else
- {
- if (_arguments.size() < 1)
- {
- ERR << "Required argument missing." << endl;
- report_required_arg_missing( out(), _command_help );
- setExitCode(ZYPPER_EXIT_ERR_INVALID_ARGS);
- return;
- }
-
- initRepoManager();
-
- std::set<repo::RepoInfoBase_Ptr, ServiceAliasComparator> to_remove;
- for_(it, _arguments.begin(), _arguments.end())
- {
- repo::RepoInfoBase_Ptr s;
- if (match_service(*this, *it, s))
- {
- to_remove.insert(s);
- }
- else
- {
- MIL << "Service not found by given alias, number or URI." << endl;
- // translators: %s is the supplied command line argument which
- // for which no service counterpart was found
- out().error( str::Format(_("Service '%s' not found by alias, number or URI.")) % *it );
- }
- }
-
- for_(it, to_remove.begin(), to_remove.end())
- {
- RepoInfo_Ptr repo_ptr = dynamic_pointer_cast<RepoInfo>(*it);
- if (repo_ptr)
- remove_repo(*this, *repo_ptr);
- else
- remove_service(*this, *dynamic_pointer_cast<ServiceInfo>(*it));
- }
- }
-
- break;
- }
-
- // --------------------------( rename repo )--------------------------------
-
- case ZypperCommand::RENAME_REPO_e:
- {
- // check root user
- if ( geteuid() != 0 && !globalOpts().changedRoot )
- {
- out().error(_("Root privileges are required for modifying system repositories.") );
- setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
- return;
- }
-
- if ( _arguments.size() < 2 )
- {
- out().error(_("Too few arguments. At least URI and alias are required.") );
- ERR << "Too few arguments. At least URI and alias are required." << endl;
- out().info( _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
- // too many arguments
- else if ( _arguments.size() > 2 )
- {
- report_too_many_arguments( _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
-
- initRepoManager();
- try
- {
- RepoInfo repo;
- if ( match_repo( *this,_arguments[0], &repo ))
- {
- rename_repo( *this, repo.alias(), _arguments[1] );
- }
- else
- {
- out().error( str::Format(_("Repository '%s' not found.")) % _arguments[0] );
- ERR << "Repo " << _arguments[0] << " not found" << endl;
- }
- }
- catch ( const Exception & excpt_r )
- {
- out().error( excpt_r.asUserString() );
- setExitCode( ZYPPER_EXIT_ERR_ZYPP );
- return;
- }
+ {
+ if ( runningHelp() )
+ break;
- return;
+ ERR << "Unknown or unexpected command" << endl;
+ out().error(_("Unexpected program flow."));
+ report_a_bug( out() );
+ }
}
- // --------------------------( modify repo )--------------------------------
+ // no need to parse command options if we already know we just want help
+ if ( runningHelp() )
+ return;
- case ZypperCommand::MODIFY_REPO_e:
+ // parse command options
+ _copts = parse_options( argc(), argv(), specific_options );
+ if ( _copts.count("_unknown") || _copts.count("_missing_arg") )
{
- // check root user
- if ( geteuid() != 0 && !globalOpts().changedRoot )
- {
- out().error(_("Root privileges are required for modifying system repositories.") );
- setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
- return;
- }
+ setExitCode( ZYPPER_EXIT_ERR_SYNTAX );
+ ERR << "Unknown option or missing argument, returning." << endl;
+ return;
+ }
- bool aggregate = copts.count("all") || copts.count("local") || copts.count("remote") || copts.count("medium-type");
+ // Leagcy cli translations (mostly from rug to zypper)
+ legacyCLITranslate( _copts, "agree-to-third-party-licenses", "auto-agree-with-licenses" );
+ legacyCLITranslate( _copts, "sort-by-catalog", "sort-by-repo" );
+ legacyCLITranslate( _copts, "uninstalled-only", "not-installed-only", Out::HIGH ); // bsc#972997: Prefer --not-installed-only over misleading --uninstalled-only
- if ( _arguments.size() < 1 && !aggregate )
+ // bsc#957862: pkg/apt/yum user convenience: no-confirm ==> --non-interactive
+ if ( _copts.count("no-confirm") )
+ {
+ if ( ! _gopts.non_interactive )
{
- report_alias_or_aggregate_required ( out(), _command_help );
- ERR << "No alias argument given." << endl;
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
+ out().info(_("Entering non-interactive mode."), Out::HIGH );
+ MIL << "Entering non-interactive mode" << endl;
+ _gopts.non_interactive = true;
}
+ }
- // too many arguments
- if ( _arguments.size() && aggregate )
- {
- report_too_many_arguments( _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
+ ::copts = _copts;
+ MIL << "Done parsing options." << endl;
- initRepoManager();
- if ( aggregate )
- {
- modify_repos_by_option( *this );
- }
- else
+ // treat --help command option like global --help option from now on
+ // i.e. when used together with command to print command specific help
+ setRunningHelp( runningHelp() || copts.count("help") );
+
+ if ( optind < argc() )
+ {
+ std::ostringstream s;
+ s << _("Non-option program arguments: ");
+ while ( optind < argc() )
{
- for_( arg,_arguments.begin(),_arguments.end() )
- {
- RepoInfo r;
- if ( match_repo(*this,*arg,&r) )
- {
- modify_repo( *this, r.alias() );
- }
- else
- {
- out().error( str::Format(_("Repository %s not found.")) % *arg );
- ERR << "Repo " << *arg << " not found" << endl;
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- }
- }
+ std::string argument = argv()[optind++];
+ s << "'" << argument << "' ";
+ _arguments.push_back( argument );
}
-
- break;
+ out().info( s.str(), Out::HIGH );
}
- // --------------------------( refresh )------------------------------------
+ MIL << "Done " << endl;
+}
- case ZypperCommand::REFRESH_e:
+/// process one command from the OS shell or the zypper shell
+void Zypper::doCommand()
+{
+ // help check is common to all commands
+ if ( runningHelp() )
{
- // check root user
- if ( geteuid() != 0 && !globalOpts().changedRoot )
- {
- out().error(_("Root privileges are required for refreshing system repositories.") );
- setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
- return;
- }
+ out().info( _command_help, Out::QUIET );
+ if ( command() == ZypperCommand::SEARCH )
+ SLE15_SearchPackagesHintHack( *this );
+ return;
+ }
- if ( globalOpts().no_refresh )
- out().warning( str::Format(_("The '%s' global option has no effect here.")) % "--no-refresh" );
+ // === ZYpp lock ===
+ switch ( command().toEnum() )
+ {
+ case ZypperCommand::PS_e:
+ case ZypperCommand::SUBCOMMAND_e:
+ // bnc#703598: Quick fix as few commands do not need a zypp lock
+ break;
- // by default refresh only repositories
- initRepoManager();
- if ( copts.count("services") )
- {
- if ( !_arguments.empty() )
+ default:
+ if ( _gopts.changedRoot && _gopts.root_dir != "/" )
{
- out().error(str::form(_("Arguments are not allowed if '%s' is used."), "--services"));
- setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
- return;
+ // bnc#575096: Quick fix
+ ::setenv( "ZYPP_LOCKFILE_ROOT", _gopts.root_dir.c_str(), 0 );
}
- // needed to be able to retrieve target distribution
- init_target( *this );
- _gopts.rm_options.servicesTargetDistro = God->target()->targetDistribution();
- refresh_services( *this );
- }
- else
- {
- checkIfToRefreshPluginServices( *this );
- }
- refresh_repos( *this );
- break;
+ {
+ const char *roh = getenv( "ZYPP_READONLY_HACK" );
+ if ( roh != NULL && roh[0] == '1' )
+ zypp_readonly_hack::IWantIt ();
+
+ else if ( command() == ZypperCommand::LIST_REPOS
+ || command() == ZypperCommand::LIST_SERVICES
+ || command() == ZypperCommand::VERSION_CMP
+ || command() == ZypperCommand::TARGET_OS )
+ zypp_readonly_hack::IWantIt (); // #247001, #302152
+ }
+ assertZYppPtrGod();
+ }
+ // === execute command ===
+
+ if ( !checkRequiredCapabilities( *this, _gopts ) ) {
+ setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
+ return;
}
- // --------------------------( clean )------------------------------------
+ MIL << "Going to process command " << command() << endl;
+
+ //handle new style commands
+ ZypperBaseCommandPtr newStyleCmd = command().commandObject();
+ if ( newStyleCmd ) {
+ setExitCode( newStyleCmd->run(*this, _arguments) );
+ return;
+ }
- case ZypperCommand::CLEAN_e:
+ ResObject::Kind kind;
+ switch( command().toEnum() )
{
- // check root user
- if ( geteuid() != 0 && !globalOpts().changedRoot )
- {
- out().error(_("Root privileges are required for cleaning local caches.") );
- setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
- return;
- }
- initRepoManager();
- clean_repos( *this );
+ // --------------------------( moo )----------------------------------------
+
+ case ZypperCommand::MOO_e:
+ {
+ // TranslatorExplanation this is a hedgehog, paint another animal, if you want
+ out().info(_(" \\\\\\\\\\\n \\\\\\\\\\\\\\__o\n__\\\\\\\\\\\\\\'/_"));
break;
}
// shut up zypper
SCOPED_VERBOSITY( out(), Out::QUIET );
- refresh_repo( *this, repo );
+ RefreshRepoCmd::refreshRepository( *this, repo );
runtimeData().temporary_repos.push_back( repo );
}
// no rpms and no other arguments either
return;
}
- // -----------------------------( locks )------------------------------------
-
- case ZypperCommand::ADD_LOCK_e:
- {
- // check root user
- if ( geteuid() != 0 && !globalOpts().changedRoot )
- {
- out().error(_("Root privileges are required for adding of package locks.") );
- setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
- return;
- }
-
- // too few arguments
- if ( _arguments.empty() )
- {
- report_required_arg_missing( out(), _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
-
- ResKindSet kinds;
- if ( copts.count("type") )
- {
- for_( it, copts["type"].begin(), copts["type"].end() )
- {
- kind = string_to_kind( *it );
- if ( kind == ResObject::Kind() )
- {
- out().error( str::Format(_("Unknown package type '%s'.")) % *it );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
- kinds.insert( kind );
- }
- }
- //else
- // let add_locks determine the appropriate type (bnc #551956)
-
- add_locks( *this, _arguments, kinds );
-
- break;
- }
-
- case ZypperCommand::REMOVE_LOCK_e:
- {
- // check root user
- if ( geteuid() != 0 && !globalOpts().changedRoot )
- {
- out().error(_("Root privileges are required for adding of package locks.") );
- setExitCode( ZYPPER_EXIT_ERR_PRIVILEGES );
- return;
- }
-
- if ( _arguments.empty() )
- {
- report_required_arg_missing( out(), _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
-
- ResKindSet kinds;
- if ( copts.count("type") )
- {
- for_( it, copts["type"].begin(), copts["type"].end() )
- {
- kind = string_to_kind( *it );
- if ( kind == ResObject::Kind() )
- {
- out().error( str::Format(_("Unknown package type '%s'.")) % *it );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
- kinds.insert( kind );
- }
- }
- //else
- // let remove_locks determine the appropriate type
-
- remove_locks( *this, _arguments, kinds );
-
- break;
- }
-
- case ZypperCommand::CLEAN_LOCKS_e:
- {
- initRepoManager();
- init_target( *this );
- init_repos( *this );
- if ( exitCode() != ZYPPER_EXIT_OK )
- return;
- load_resolvables( *this );
-
- Locks::instance().read();
- Locks::size_type start = Locks::instance().size();
- if ( !copts.count("only-duplicate") )
- Locks::instance().removeEmpty();
- if ( !copts.count("only-empty") )
- Locks::instance().removeDuplicates();
-
- Locks::instance().save();
-
- Locks::size_type diff = start - Locks::instance().size();
- out().info( str::form( PL_("Removed %lu lock.","Removed %lu locks.", diff), (long unsigned)diff ) );
-
- break;
- }
-
// ----------------------------(utils/others)--------------------------------
case ZypperCommand::TARGET_OS_e:
break;
}
-
- case ZypperCommand::PS_e:
- {
- if ( !_arguments.empty() )
- {
- report_too_many_arguments( _command_help );
- setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
-
- shared_ptr<PsOptions> myOpts( assertCommandOptions<PsOptions>() );
- if ( _copts.count( "print" ) )
- {
- // implies -sss
- myOpts->_shortness = 3;
- myOpts->_format = _copts["print"].back(); // last wins
- }
- else if ( _copts.count( "short" ) )
- {
- myOpts->_shortness = _copts["short"].size();
- }
- else if ( _copts.count( "debugFile" ) )
- {
- myOpts->_debugFile = _copts["debugFile"].front();
- }
-
- ps( *this );
- break;
- }
-
-
case ZypperCommand::DOWNLOAD_e:
{
if ( _arguments.empty() )
} // namespace cli
///////////////////////////////////////////////////////////////////
+/** Flags for tuning \ref Zypper::defaultLoadSystem. */
+enum LoadSystemBits
+{
+ NoTarget = (1 << 0), //< don't load target to pool
+ NoRepos = (1 << 1), //< don't load repos to pool
+ NoPool = NoTarget | NoRepos //< no pool at all
+};
+ZYPP_DECLARE_FLAGS( LoadSystemFlags, LoadSystemBits );
+
+/** \relates LoadSystemFlags */
+ZYPP_DECLARE_OPERATORS_FOR_FLAGS( LoadSystemFlags );
+
/**
* Structure for holding global options.
*
#include <boost/optional.hpp>
#include "utils/flags/flagtypes.h"
#include "commandhelpformatter.h"
+#include "solve-commit.h"
+
+#include "src/repos.h"
using namespace zypp;
+extern ZYpp::Ptr God;
+
BaseCommandOptionSet::BaseCommandOptionSet()
{
}
}
+ZypperBaseCommand::ZypperBaseCommand(const std::vector<std::string> &commandAliases_r, const std::string &synopsis_r,
+ const std::string &summary_r, const std::string &description_r,
+ SetupSystemFlags systemInitFlags_r)
+ : ZypperBaseCommand( commandAliases_r, std::vector<std::string>{synopsis_r}, summary_r, description_r, systemInitFlags_r )
+{
+
+}
+
+ZypperBaseCommand::ZypperBaseCommand(const std::vector<std::string> &commandAliases_r, const std::vector<std::string> &synopsis_r,
+ const std::string &summary_r, const std::string &description_r,
+ SetupSystemFlags systemInitFlags_r)
+ : _commandAliases ( commandAliases_r ),
+ _synopsis ( synopsis_r ),
+ _summary ( summary_r ),
+ _description ( description_r ),
+ _systemInitFlags ( systemInitFlags_r )
+{
+
+}
+
ZypperBaseCommand::~ZypperBaseCommand()
{
}
doReset();
}
+std::vector<std::string> ZypperBaseCommand::command() const
+{
+ return _commandAliases;
+}
+
+std::string ZypperBaseCommand::summary() const
+{
+ return _summary;
+}
+
+std::vector<std::string> ZypperBaseCommand::synopsis() const
+{
+ return _synopsis;
+}
+
+std::string ZypperBaseCommand::description() const
+{
+ return _description;
+}
+
bool ZypperBaseCommand::helpRequested() const
{
return _helpRequested;
}
+SetupSystemFlags ZypperBaseCommand::setupSystemFlags() const
+{
+ return _systemInitFlags;
+}
+
+ZYpp::Ptr ZypperBaseCommand::zyppApi() const
+{
+ return God;
+}
+
std::vector<BaseCommandConditionPtr> ZypperBaseCommand::conditions() const
{
return std::vector<BaseCommandConditionPtr>();
}
-LoadSystemFlags ZypperBaseCommand::needSystemSetup() const
+int ZypperBaseCommand::systemSetup( Zypper &zypp_r )
+{
+ return defaultSystemSetup ( zypp_r, _systemInitFlags );
+}
+
+int ZypperBaseCommand::defaultSystemSetup( Zypper &zypp_r, SetupSystemFlags flags_r )
{
- //we want all by default
- return LoadSystemFlags();
+ DBG << "FLAGS:" << flags_r << endl;
+
+ if ( flags_r.testFlag( ResetRepoManager ) )
+ zypp_r.initRepoManager();
+
+ if ( flags_r.testFlag( InitTarget ) ) {
+ init_target( zypp_r );
+ if ( zypp_r.exitCode() != ZYPPER_EXIT_OK )
+ return zypp_r.exitCode();
+ }
+
+ if ( flags_r.testFlag( InitRepos ) ) {
+ init_repos( zypp_r );
+ if ( zypp_r.exitCode() != ZYPPER_EXIT_OK )
+ return zypp_r.exitCode();
+ }
+
+ DtorReset _tmp( zypp_r.globalOptsNoConst().disable_system_resolvables );
+ if ( flags_r.testFlag( LoadResolvables ) ) {
+ if ( flags_r.testFlag( NoSystemResolvables ) ) {
+ zypp_r.globalOptsNoConst().disable_system_resolvables = true;
+ }
+
+ load_resolvables( zypp_r );
+ if ( zypp_r.exitCode() != ZYPPER_EXIT_OK )
+ return zypp_r.exitCode();
+ }
+
+ if ( flags_r.testFlag ( Resolve ) ) {
+ // have REPOS and TARGET
+ // compute status of PPP
+ resolve( zypp_r );
+ }
+
+ return zypp_r.exitCode();
}
int ZypperBaseCommand::run(Zypper &zypp, const std::vector<std::string> &positionalArgs)
MIL << "run: " << command().front() << endl;
try
{
- for ( const BaseCommandConditionPtr cond : conditions() ) {
+ for ( const BaseCommandConditionPtr &cond : conditions() ) {
std::string error;
int code = cond->check( error );
if ( code != 0 ) {
}
}
+ int code = systemSetup( zypp );
+ if ( code != ZYPPER_EXIT_OK )
+ return code;
+
return execute( zypp, positionalArgs );
}
catch ( const Out::Error & error_r )
std::string ZypperBaseCommand::help()
{
CommandHelpFormater help;
- help.synopsis(synopsis())
- .description(description());
+ for ( const std::string &syn : synopsis() )
+ help.synopsis(syn);
+ help.description(description());
+
+ auto renderOption = [&help]( const ZyppFlags::CommandOption &opt ) {
+ std::string optTxt;
+ if ( opt.shortName )
+ optTxt.append( str::Format("-%1%, ") % opt.shortName);
+ optTxt.append("--").append(opt.name);
+
+ std::string argSyntax = opt.value.argHint();
+ if ( argSyntax.length() ) {
+ if ( opt.flags & ZyppFlags::OptionalArgument )
+ optTxt.append("[=");
+ else
+ optTxt.append(" <");
+ optTxt.append(argSyntax);
+ if ( opt.flags & ZyppFlags::OptionalArgument )
+ optTxt.append("]");
+ else
+ optTxt.append(">");
+ }
+
+ std::string optHelpTxt = opt.help;
+ auto defVal = opt.value.defaultValue();
+ if ( defVal )
+ optHelpTxt.append(" ").append(str::Format(("Default: %1%")) %*defVal );
+ help.option(optTxt, optHelpTxt);
+ };
+
+ //all the options we have
+ std::vector<ZyppFlags::CommandGroup> opts = options();
+
+ //collect all deprecated options
+ std::vector<const ZyppFlags::CommandOption*> legacyOptions;
bool hadOptions = false;
- for ( const ZyppFlags::CommandGroup &grp : options() ) {
+ for ( const ZyppFlags::CommandGroup &grp : opts ) {
if ( grp.options.size() ) {
- hadOptions = true;
- help.optionSection( grp.name );
+ bool wroteSectionHdr = false;
for ( const ZyppFlags::CommandOption &opt : grp.options ) {
if ( opt.flags & ZyppFlags::Hidden )
continue;
-
- std::string optTxt;
- if ( opt.shortName )
- optTxt.append( str::Format("-%1%, ") % opt.shortName);
- optTxt.append("--").append(opt.name);
-
- std::string argSyntax = opt.value.argHint();
- if ( argSyntax.length() ) {
- if ( opt.flags & ZyppFlags::OptionalArgument )
- optTxt.append("[=");
- else
- optTxt.append(" <");
- optTxt.append(argSyntax);
- if ( opt.flags & ZyppFlags::OptionalArgument )
- optTxt.append("]");
- else
- optTxt.append(">");
+ if ( opt.flags & ZyppFlags::Deprecated ) {
+ legacyOptions.push_back( &opt );
+ continue;
}
-
- std::string optHelpTxt = opt.help;
- auto defVal = opt.value.defaultValue();
- if ( defVal )
- optHelpTxt.append(str::Format(_(" Default: %1%")) %*defVal );
- help.option(optTxt, optHelpTxt);
+ //write the section header only if we actuall have entries
+ if ( !wroteSectionHdr ) {
+ wroteSectionHdr = true;
+ help.optionSection( grp.name );
+ }
+ hadOptions = true;
+ renderOption(opt);
}
}
}
+ if ( legacyOptions.size() ) {
+ help.legacyOptionSection();
+ for ( const ZyppFlags::CommandOption *legacyOption : legacyOptions ) {
+ renderOption(*legacyOption);
+ }
+ }
+
+ if ( !hadOptions ) {
+ help.noOptionSection();
+ }
+
return help;
}
std::vector<ZyppFlags::CommandGroup> ZypperBaseCommand::options()
{
//first get the commands own options
- std::vector<ZyppFlags::CommandGroup> allOpts {
- { _("Options:"), cmdOptions() }
- };
-
- ZyppFlags::CommandOption helpOpt{
- "help", 'h', ZyppFlags::NoArgument | ZyppFlags::Hidden, ZyppFlags::BoolType( &_helpRequested ), ""
+ std::vector<ZyppFlags::CommandGroup> allOpts;
+
+ //merges a group into
+ auto mergeGroup = [ &allOpts ] ( ZyppFlags::CommandGroup &&grp ) {
+ bool foundCmdGroup = false;
+ for ( ZyppFlags::CommandGroup &cmdGroup : allOpts ) {
+ if ( grp.name == cmdGroup.name ) {
+ foundCmdGroup = true;
+ std::move( grp.options.begin(), grp.options.end(), std::back_inserter(cmdGroup.options) );
+ std::move( grp.conflictingOptions.begin(), grp.conflictingOptions.end(), std::back_inserter(cmdGroup.conflictingOptions) );
+ }
+ }
+ if ( !foundCmdGroup )
+ allOpts.push_back( std::move(grp) );
};
//inject a help option at the beginning, we always want help
- allOpts.front().options.insert( allOpts.front().options.end(), std::move(helpOpt));
+ //this will also make sure that the default command group is at the beginning
+ mergeGroup ( ZyppFlags::CommandGroup {{
+ { "help", 'h', ZyppFlags::NoArgument | ZyppFlags::Hidden, ZyppFlags::BoolType( &_helpRequested ), "" }
+ }});
+
+ // now add the commands own options
+ mergeGroup ( cmdOptions() );
//now collect all options from registered option sets
for ( BaseCommandOptionSet *set : _registeredOptionSets ) {
//merge the set into the other options
for ( ZyppFlags::CommandGroup &grp : setOpts ) {
- bool foundCmdGroup = false;
- for ( ZyppFlags::CommandGroup &cmdGroup : allOpts ) {
- if ( grp.name == cmdGroup.name ) {
- foundCmdGroup = true;
- std::move(grp.options.begin(), grp.options.end(), std::back_inserter(cmdGroup.options));
- }
- }
- if ( !foundCmdGroup )
- allOpts.push_back( grp );
+ mergeGroup ( std::move(grp) );
}
}
-
return allOpts;
}
#ifndef ZYPPER_COMMANDS_BASECOMMAND_INCLUDED
#define ZYPPER_COMMANDS_BASECOMMAND_INCLUDED
-#include <list>
+#include <vector>
#include <string>
#include <memory>
#include "zypp/base/Flags.h"
#include "utils/flags/zyppflags.h"
+#include <zypp/ZYpp.h>
+
class Zypper;
class ZypperBaseCommand;
};
using BaseCommandConditionPtr = std::shared_ptr<BaseCommandCondition>;
-
-/** Flags for tuning \ref Zypper::defaultLoadSystem. */
-enum LoadSystemBits
+/** Flags for tuning \ref ZypperBaseCommand::defaultSystemSetup. */
+enum SetupSystemBits
{
- NO_TARGET = (1 << 0), //< don't load target to pool
- NO_REPOS = (1 << 1), //< don't load repos to pool
- NO_POOL = NO_TARGET | NO_REPOS //< no pool at all
+ DisableAll = 0,
+ ResetRepoManager = (1 << 1), //< explicitely reset the repomanager before calling the cmd
+ InitTarget = (1 << 2), //< Initialize the target
+ InitRepos = (1 << 3), //< Initialize repositories
+ NoSystemResolvables = (1 << 4), //< Disable the loading of system resolvables
+ LoadResolvables = (1 << 5), //< Load resolvables
+ Resolve = (1 << 6), //< compute status of PPP
+ DefaultSetup = ResetRepoManager | InitTarget | InitRepos | LoadResolvables | Resolve
};
-ZYPP_DECLARE_FLAGS( LoadSystemFlags, LoadSystemBits );
+ZYPP_DECLARE_FLAGS( SetupSystemFlags, SetupSystemBits );
/** \relates LoadSystemFlags */
-ZYPP_DECLARE_OPERATORS_FOR_FLAGS( LoadSystemFlags );
+ZYPP_DECLARE_OPERATORS_FOR_FLAGS( SetupSystemFlags );
+
+
+
/**
* All Zypper commands should derive from this type. It automatically
public:
friend class BaseCommandOptionSet;
+ ZypperBaseCommand ( const std::vector<std::string> &commandAliases_r,
+ const std::string &synopsis_r,
+ const std::string &summary_r = std::string(),
+ const std::string &description_r = std::string(),
+ SetupSystemFlags systemInitFlags_r = DefaultSetup
+ );
+
+ ZypperBaseCommand ( const std::vector<std::string> &commandAliases_r,
+ const std::vector<std::string> &synopsis_r,
+ const std::string &summary_r = std::string(),
+ const std::string &description_r = std::string(),
+ SetupSystemFlags systemInitFlags_r = DefaultSetup
+ );
+
virtual ~ZypperBaseCommand();
/**
* Returns a list of command aliases that are accepted
* on the command line
*/
- virtual std::list<std::string> command () const = 0;
+ virtual std::vector<std::string> command () const;
/**
* Returns the command summary, a one line description
* of what it does. Used in "zypper help" command overview.
* \sa help
*/
- virtual std::string summary () const = 0;
+ virtual std::string summary () const;
/**
* Returns the synopsis of how the command is to be called.
* \example "list (ll) [options]"
* \sa help
*/
- virtual std::string synopsis () const = 0;
+ virtual std::vector<std::string> synopsis () const;
/**
* Returns a short description of what the command does, this is
* used in the commands help page.
* \sa help
*/
- virtual std::string description () const = 0;
-
- /**
- * Specifies what part of the system need to be initialized before
- * executing the command.
- * \sa LoadSystemBits
- */
- virtual LoadSystemFlags needSystemSetup () const;
+ virtual std::string description () const;
/**
* Prepares the command to be executed and checks all conditions before
*/
bool helpRequested () const;
+ /**
+ * Returns the system setup flags set by the constructor
+ * \sa systemSetup
+ * \sa defaultSystemSetup
+ */
+ SetupSystemFlags setupSystemFlags () const;
+
+ zypp::ZYpp::Ptr zyppApi () const;
+
protected:
/**
* Registers a option set to be supported on command line
/**
* Reimplement to return the commands own options.
*/
- virtual std::vector<zypp::ZyppFlags::CommandOption> cmdOptions () const = 0;
+ virtual zypp::ZyppFlags::CommandGroup cmdOptions () const = 0;
/**
* Reimplement to reset all options to the default
*/
virtual int execute ( Zypper &zypp, const std::vector<std::string> &positionalArgs ) = 0;
+ /**
+ * Sets up the system before the command is executed, reimplement to change default behaviour.
+ * The default implementation calls \sa defaultSystemSetup
+ */
+ virtual int systemSetup ( Zypper &zypp_r );
+
+ /**
+ * Initializes the system according to bits set in \a flags
+ */
+ int defaultSystemSetup(Zypper &zypp_r, SetupSystemFlags flags_r = DefaultSetup );
+
private:
std::vector<BaseCommandOptionSet *> _registeredOptionSets;
bool _helpRequested = false;
+ std::vector<std::string> _commandAliases;
+ std::vector<std::string> _synopsis;
+ std::string _summary;
+ std::string _description;
+ SetupSystemFlags _systemInitFlags;
};
using ZypperBaseCommandPtr = std::shared_ptr<ZypperBaseCommand> ;
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "conditions.h"
+#include "Zypper.h"
+
+#include <sys/vfs.h>
+#include <sys/statvfs.h>
+#include <linux/magic.h>
+
+int NeedsRootCondition::check(std::string &err)
+{
+ if ( geteuid() != 0 && !Zypper::instance().globalOpts().changedRoot )
+ {
+ err = _("Root privileges are required to run this command.");
+ return ZYPPER_EXIT_ERR_PRIVILEGES;
+ }
+ return ZYPPER_EXIT_OK;
+}
+
+int NeedsWritableRoot::check(std::string &err_r)
+{
+ Zypper &zypper = Zypper::instance();
+ const GlobalOptions &gopts = zypper.globalOpts();
+
+ if ( zypper.cOpts().count("dry-run") )
+ return ZYPPER_EXIT_OK;
+
+ struct statfs fsinfo;
+ memset( &fsinfo, 0, sizeof(struct statfs) );
+
+ int errCode = 0;
+ do {
+ errCode = statfs( gopts.root_dir.c_str(), &fsinfo );
+ } while ( errCode == -1 && errno == EINTR );
+
+ if ( !errCode ) {
+ if ( fsinfo.f_flags & ST_RDONLY ) {
+
+ bool isTransactionalServer = ( fsinfo.f_type == BTRFS_SUPER_MAGIC && PathInfo( "/usr/sbin/transactional-update" ).isFile() );
+
+ if ( isTransactionalServer && !gopts.changedRoot ) {
+ err_r = _("This is a transactional-server, please use transactional-update to update or modify the system.");
+ } else {
+ err_r = _("The target filesystem is mounted as read-only. Please make sure the target filesystem is writeable.");
+ }
+
+ ERR << err_r << endl;
+ return ZYPPER_EXIT_ERR_PRIVILEGES;
+ }
+ } else {
+ WAR << "Checking if " << gopts.root_dir << " is mounted read only failed with errno : " << errno << std::endl;
+ }
+ return ZYPPER_EXIT_OK;
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_CONDITIONS_H_INCLUDED
+#define ZYPPER_COMMANDS_CONDITIONS_H_INCLUDED
+
+#include "basecommand.h"
+
+class NeedsRootCondition : public BaseCommandCondition
+{
+public:
+ // BaseCommandCondition interface
+ int check(std::string &err) override;
+};
+
+class NeedsWritableRoot : public BaseCommandCondition
+{
+public:
+ // BaseCommandCondition interface
+ int check(std::string &err_r) override;
+};
+
+#endif
#include "locks/add.h"
#include "locks/remove.h"
#include "locks/list.h"
+#include "locks/clean.h"
#endif
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "add.h"
+
+#include <iostream>
+
+#include <zypp/base/String.h>
+#include <zypp/base/Logger.h>
+#include <zypp/Locks.h>
+
+#include "utils/flags/flagtypes.h"
+
+#include "Zypper.h"
+#include "repos.h"
+#include "utils/messages.h"
+#include "commands/conditions.h"
+
+using namespace zypp;
+
+AddLocksCmd::AddLocksCmd( const std::vector<std::string> &commandAliases_r ) :
+ ZypperBaseCommand (
+ commandAliases_r,
+ // translators: command synopsis; do not translate the command 'name (abbreviations)' or '-option' names
+ _("addlock (al) [OPTIONS] <PACKAGENAME> ..."),
+ // translators: command summary
+ _("Add a package lock."),
+ // translators: command description
+ _("Add a package lock. Specify packages to lock by exact name or by a glob pattern using '*' and '?' wildcard characters."),
+ DisableAll )
+{ }
+
+ZyppFlags::CommandGroup AddLocksCmd::cmdOptions() const
+{
+ auto that = const_cast<AddLocksCmd *>(this);
+ return {{
+ { "type", 't', ZyppFlags::RequiredArgument, ZyppFlags::KindSetType ( &that->_kinds ) , str::Format(_("Type of package (%1%).") ) % "package, patch, pattern, product" },
+ { "repo", 'r', ZyppFlags::RequiredArgument | ZyppFlags::Repeatable, ZyppFlags::StringVectorType ( &that->_repos, "ALIAS|#|URI" ), _("Restrict the lock to the specified repository.")},
+ { "catalog", 'c', ZyppFlags::RequiredArgument | ZyppFlags::Repeatable | ZyppFlags::Hidden, ZyppFlags::StringVectorType ( &that->_repos, "ALIAS|#|URI"), "Alias for --repo" }
+ }};
+}
+
+void AddLocksCmd::doReset()
+{
+ _kinds.clear();
+ _repos.clear();
+}
+
+int AddLocksCmd::execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r)
+{
+ // too few arguments
+ if ( positionalArgs_r.empty() )
+ {
+ report_required_arg_missing( zypp_r.out(), help() );
+ return ZYPPER_EXIT_ERR_INVALID_ARGS;
+ }
+
+ try
+ {
+ Locks & locks = Locks::instance();
+ locks.read(Pathname::assertprefix
+ (zypp_r.globalOpts().root_dir, ZConfig::instance().locksFile()));
+ Locks::size_type start = locks.size();
+ for_(it,positionalArgs_r.begin(),positionalArgs_r.end())
+ {
+ PoolQuery q;
+ if ( _kinds.empty() ) // derive it from the name
+ {
+ sat::Solvable::SplitIdent split( *it );
+ q.addAttribute( sat::SolvAttr::name, split.name().asString() );
+ q.addKind( split.kind() );
+ }
+ else
+ {
+ q.addAttribute(sat::SolvAttr::name, *it);
+ for_(itk, _kinds.begin(), _kinds.end()) {
+ q.addKind(*itk);
+ }
+ }
+ q.setMatchGlob();
+ parsed_opts::const_iterator itr;
+ //TODO rug compatibility for more arguments with version restrict
+ for_(it_repo, _repos.begin(), _repos.end())
+ {
+ RepoInfo info;
+ if( match_repo( zypp_r, *it_repo, &info))
+ q.addRepo(info.alias());
+ else //TODO some error handling
+ WAR << "unknown repository" << *it_repo << endl;
+ }
+ q.setCaseSensitive();
+
+ locks.addLock(q);
+ }
+ locks.save(Pathname::assertprefix
+ (zypp_r.globalOpts().root_dir, ZConfig::instance().locksFile()));
+ if ( start != Locks::instance().size() )
+ zypp_r.out().info(PL_(
+ "Specified lock has been successfully added.",
+ "Specified locks have been successfully added.",
+ Locks::instance().size() - start));
+ }
+ catch(const Exception & e)
+ {
+ ZYPP_CAUGHT(e);
+ zypp_r.out().error(e, _("Problem adding the package lock:"));
+ return ZYPPER_EXIT_ERR_ZYPP;
+ }
+ return ZYPPER_EXIT_OK;
+}
+
+std::vector<BaseCommandConditionPtr> AddLocksCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_LOCKS_ADD_H_INCLUDED
+#define ZYPPER_COMMANDS_LOCKS_ADD_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "utils/flags/zyppflags.h"
+
+#include <zypp/ResKind.h>
+#include <set>
+
+class AddLocksCmd : public ZypperBaseCommand
+{
+public:
+ AddLocksCmd( const std::vector<std::string> &commandAliases_r );
+
+protected:
+ // ZypperBaseCommand interface
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r) override;
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+
+private:
+ std::set<zypp::ResKind> _kinds;
+ std::vector<std::string> _repos;
+};
+
+
+
+#endif
--- /dev/null
+#include "clean.h"
+
+#include <zypp/Locks.h>
+
+#include "main.h"
+#include "Zypper.h"
+#include "commands/conditions.h"
+#include "utils/flags/flagtypes.h"
+#include "utils/messages.h"
+
+using namespace zypp;
+
+CleanLocksCmd::CleanLocksCmd(const std::vector<std::string> &commandAliases_r) :
+ ZypperBaseCommand (
+ commandAliases_r,
+ _("cleanlocks (cl)"),
+ // translators: command summary
+ _("Remove useless locks."),
+ std::string()
+ )
+{ }
+
+std::vector<BaseCommandConditionPtr> CleanLocksCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
+
+ZyppFlags::CommandGroup CleanLocksCmd::cmdOptions() const
+{
+ auto that = const_cast<CleanLocksCmd *>(this);
+ return {{
+ {"only-duplicates", 'd', ZyppFlags::NoArgument, ZyppFlags::BoolType(&that->_onlyDuplicates, ZyppFlags::StoreTrue, _onlyDuplicates),
+ // translators: -d, --only-duplicates
+ _("Clean only duplicate locks.")},
+ {"only-empty", 'e', ZyppFlags::NoArgument, ZyppFlags::BoolType(&that->_onlyEmpty, ZyppFlags::StoreTrue, _onlyEmpty),
+ // translators: -e, --only-empty
+ _("Clean only locks which doesn't lock anything.") },
+ }};
+}
+
+void CleanLocksCmd::doReset()
+{
+ _onlyDuplicates = false;
+ _onlyEmpty = false;
+}
+
+int CleanLocksCmd::execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r)
+{
+ if ( !positionalArgs_r.empty() ) {
+ report_too_many_arguments( help() );
+ return ZYPPER_EXIT_ERR_INVALID_ARGS;
+ }
+
+ Locks::instance().read();
+ Locks::size_type start = Locks::instance().size();
+ if ( !_onlyDuplicates )
+ Locks::instance().removeEmpty();
+ if ( !_onlyEmpty )
+ Locks::instance().removeDuplicates();
+
+ Locks::instance().save();
+
+ Locks::size_type diff = start - Locks::instance().size();
+ zypp_r.out().info( str::form( PL_("Removed %lu lock.","Removed %lu locks.", diff), (long unsigned)diff ) );
+
+ return ZYPPER_EXIT_OK;
+}
+
+std::string CleanLocksCmd::description() const
+{
+ return summary();
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_LOCKS_CLEAN_H_INCLUDED
+#define ZYPPER_COMMANDS_LOCKS_CLEAN_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "utils/flags/zyppflags.h"
+
+#include <zypp/ResKind.h>
+#include <set>
+
+class CleanLocksCmd : public ZypperBaseCommand
+{
+public:
+ CleanLocksCmd( const std::vector<std::string> &commandAliases_r );
+
+ // ZypperBaseCommand interface
+ std::string description() const override;
+
+protected:
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp, const std::vector<std::string> &positionalArgs) override;
+private:
+ bool _onlyDuplicates = false;
+ bool _onlyEmpty = false;
+};
+
+
+
+#endif
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
#include "list.h"
#include <iostream>
#include "main.h"
#include "Table.h"
#include "utils/misc.h"
-#include "locks.h"
#include "repos.h"
};
}
-std::list<std::string> ListLocksCmd::command() const
-{
- return { "locks", "ll", "lock-list" };
-}
-
-std::string ListLocksCmd::summary() const
-{
- return _("List current package locks.");
-}
-
-std::string ListLocksCmd::synopsis() const
-{
- // translators: command synopsis; do not translate lowercase words
- return _("locks (ll) [OPTIONS]");
-}
+ListLocksCmd::ListLocksCmd(const std::vector<std::string> &commandAliases_r) :
+ ZypperBaseCommand (
+ commandAliases_r,
+ // translators: command synopsis; do not translate the command 'name (abbreviations)' or '-option' names
+ _("locks (ll) [OPTIONS]"),
+ _("List current package locks.")
+ )
+{}
std::string ListLocksCmd::description() const
{
return summary();
}
-LoadSystemFlags ListLocksCmd::needSystemSetup() const
+
+int ListLocksCmd::systemSetup(Zypper &zypp_r)
{
+ SetupSystemFlags flags = DisableAll;
if ( _matches || _solvables )
- return LoadSystemFlags();
- return NO_POOL;
+ flags.setFlag( DefaultSetup );
+ return defaultSystemSetup( zypp_r, flags );
}
void ListLocksCmd::doReset()
_solvables = false;
}
-std::vector<ZyppFlags::CommandOption> ListLocksCmd::cmdOptions() const
+ZyppFlags::CommandGroup ListLocksCmd::cmdOptions() const
{
- return {
+ return {{
{
{ "matches", 'm', ZyppFlags::NoArgument, ZyppFlags::BoolType( const_cast<bool *>(&_matches), ZyppFlags::StoreTrue, _matches), _("Show the number of resolvables matched by each lock.") },
{ "solvables", 's', ZyppFlags::NoArgument, ZyppFlags::BoolType( const_cast<bool *>(&_solvables), ZyppFlags::StoreTrue, _solvables), _("List the resolvables matched by each lock.")}
}
- };
+ }};
}
int ListLocksCmd::execute(Zypper &zypper, const std::vector<std::string> &positionalArgs)
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
#ifndef ZYPPER_COMMANDS_LOCKS_LIST_H_INCLUDED
#define ZYPPER_COMMANDS_LOCKS_LIST_H_INCLUDED
class ListLocksCmd : public ZypperBaseCommand
{
- // ZypperBaseCommand interface
public:
- std::list<std::string> command() const override;
- std::string summary() const override;
- std::string synopsis() const override;
+ ListLocksCmd( const std::vector<std::string> &commandAliases_r );
+
+ // ZypperBaseCommand interface
std::string description() const override;
- LoadSystemFlags needSystemSetup() const override;
protected:
int execute(Zypper &zypper, const std::vector<std::string> &positionalArgs) override;
- std::vector<zypp::ZyppFlags::CommandOption> cmdOptions() const override;
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
void doReset() override;
+ int systemSetup(Zypper &zypp_r) override;
private:
bool _matches = false;
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "remove.h"
+
+#include <boost/lexical_cast.hpp>
+
+#include <zypp/base/String.h>
+#include <zypp/Locks.h>
+
+#include "main.h"
+#include "utils/messages.h"
+#include "repos.h"
+#include "Zypper.h"
+#include "utils/flags/flagtypes.h"
+#include "commands/conditions.h"
+
+using namespace zypp;
+
+RemoveLocksCmd::RemoveLocksCmd(const std::vector<std::string> &commandAliases_r)
+ : ZypperBaseCommand(
+ commandAliases_r,
+ _("removelock (rl) [OPTIONS] <LOCK-NUMBER|PACKAGENAME> ..."),
+ _("Remove a package lock."),
+ // translators: command description; %1% is acoomand like 'zypper locks'
+ str::Format(_("Remove a package lock. Specify the lock to remove by its number obtained with '%1%' or by package name.") ) % "zypper locks",
+ DisableAll
+ )
+{ }
+
+std::vector<BaseCommandConditionPtr> RemoveLocksCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
+
+ZyppFlags::CommandGroup RemoveLocksCmd::cmdOptions() const
+{
+ auto that = const_cast<RemoveLocksCmd *>(this);
+ return {{
+ { "type", 't', ZyppFlags::RequiredArgument, ZyppFlags::KindSetType ( &that->_kinds ) , str::Format(_("Type of package (%1%).") ) % "package, patch, pattern, product" },
+ { "repo", 'r', ZyppFlags::RequiredArgument | ZyppFlags::Repeatable, ZyppFlags::StringVectorType ( &that->_repos, "ALIAS|#|URI" ), _("Remove only locks with specified repository.") },
+ { "catalog", 'c', ZyppFlags::RequiredArgument | ZyppFlags::Repeatable | ZyppFlags::Hidden, ZyppFlags::StringVectorType ( &that->_repos, "ALIAS|#|URI"), "Alias for --repo" }
+ }};
+}
+
+void RemoveLocksCmd::doReset()
+{
+ _kinds.clear();
+ _repos.clear();
+}
+
+int RemoveLocksCmd::execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r)
+{
+ // too few arguments
+ if ( positionalArgs_r.empty() )
+ {
+ report_required_arg_missing( zypp_r.out(), help() );
+ return ZYPPER_EXIT_ERR_INVALID_ARGS;
+ }
+
+ try
+ {
+ Locks & locks = Locks::instance();
+ locks.read(Pathname::assertprefix
+ (zypp_r.globalOpts().root_dir, ZConfig::instance().locksFile()));
+ Locks::size_type start = locks.size();
+ for_( args_it, positionalArgs_r.begin(), positionalArgs_r.end() )
+ {
+ Locks::const_iterator it = locks.begin();
+ Locks::LockList::size_type i = 0;
+ safe_lexical_cast(*args_it, i);
+ if (i > 0 && i <= locks.size())
+ {
+ advance(it, i-1);
+ locks.removeLock(*it);
+
+ zypp_r.out().info(_("Specified lock has been successfully removed."));
+ }
+ else //package name
+ {
+ //TODO fill query in one method to have consistent add/remove
+ //TODO what to do with repo and _kinds?
+ PoolQuery q;
+ if ( _kinds.empty() ) // derive it from the name
+ {
+ // derive kind from the name: (rl should also support -t)
+ sat::Solvable::SplitIdent split( *args_it );
+ q.addAttribute( sat::SolvAttr::name, split.name().asString() );
+ q.addKind( split.kind() );
+ }
+ else
+ {
+ q.addAttribute(sat::SolvAttr::name, *args_it);
+ for_(itk, _kinds.begin(), _kinds.end()) {
+ q.addKind(*itk);
+ }
+ }
+ q.setMatchGlob();
+ parsed_opts::const_iterator itr;
+ for_(it_repo, _repos.begin(), _repos.end())
+ {
+ RepoInfo info;
+ if( match_repo( zypp_r, *it_repo, &info))
+ q.addRepo(info.alias());
+ else //TODO some error handling
+ WAR << "unknown repository" << *it_repo << endl;
+ }
+ q.setCaseSensitive();
+
+ locks.removeLock(q);
+ }
+ }
+
+ locks.save(Pathname::assertprefix
+ (zypp_r.globalOpts().root_dir, ZConfig::instance().locksFile()));
+
+ // nothing removed
+ if (start == locks.size())
+ zypp_r.out().info(_("No lock has been removed."));
+ //removed something
+ else
+ zypp_r.out().info(str::form(PL_(
+ "%zu lock has been successfully removed.",
+ "%zu locks have been successfully removed.",
+ start - locks.size()), start - locks.size()));
+ }
+ catch(const Exception & e)
+ {
+ ZYPP_CAUGHT(e);
+ zypp_r.out().error(e, _("Problem removing the package lock:"));
+ return ZYPPER_EXIT_ERR_ZYPP;
+ }
+ return ZYPPER_EXIT_OK;
+}
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_LOCKS_REMOVE_H_INCLUDED
+#define ZYPPER_COMMANDS_LOCKS_REMOVE_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "utils/flags/zyppflags.h"
+
+#include <zypp/ResKind.h>
+#include <set>
+
+class RemoveLocksCmd : public ZypperBaseCommand
+{
+public:
+ RemoveLocksCmd( const std::vector<std::string> &commandAliases_r );
+
+ // ZypperBaseCommand interface
+protected:
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r) override;
+
+private:
+ std::set<zypp::ResKind> _kinds;
+ std::vector<std::string> _repos;
+};
+
+
+
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "ps.h"
+
+#include <iostream>
+
+#include <zypp/base/LogTools.h>
+#include <zypp/ExternalProgram.h>
+#include <zypp/misc/CheckAccessDeleted.h>
+
+#include "Zypper.h"
+#include "Table.h"
+#include "utils/messages.h"
+#include "utils/flags/flagtypes.h"
+
+using namespace zypp;
+
+PSCommand::PSCommand(const std::vector<std::string> &commandAliases_r) :
+ ZypperBaseCommand (
+ commandAliases_r,
+ // translators: command synopsis; do not translate the command 'name (abbreviations)' or '-option' names
+ _("ps [OPTIONS]"),
+ // translators: command description
+ _("List running processes which might still use files and libraries deleted by recent upgrades."),
+ std::string(),
+ DisableAll
+ )
+{ }
+
+std::string PSCommand::description() const
+{
+ return summary();
+}
+
+ZyppFlags::CommandGroup PSCommand::cmdOptions() const
+{
+ auto that = const_cast<PSCommand *>(this);
+ return {{
+ { "short", 's', ZyppFlags::NoArgument | ZyppFlags::Repeatable, ZyppFlags::CounterType( &that->_shortness, _shortness, 3)
+ // translators: -s, --short
+ , _("Create a short table not showing the deleted files. Given twice, show only processes which are associated with a system service. Given three times, list the associated system service names only.")
+ }, { "print", '\0', ZyppFlags::RequiredArgument, ZyppFlags::StringType(&that->_format, boost::optional<const char *>(), "FORMAT")
+ // translators: --print <format>
+ , _("For each associated system service print <format> on the standard output, followed by a newline. Any '%s' directive in <format> is replaced by the system service name.")
+ }, { "debugFile", 'd', ZyppFlags::RequiredArgument, ZyppFlags::StringType(&that->_debugFile, boost::optional<const char *>(), "PATH")
+ // translators: -d, --debugFile <path>
+ , _("Write debug output to file <path>.")
+ }
+ }};
+}
+
+void PSCommand::doReset()
+{
+ _shortness = 0;
+ _debugFile.clear();
+ _format.clear();
+}
+
+inline void loadData( CheckAccessDeleted & checker_r )
+{
+ try
+ {
+ checker_r.check();
+ }
+ catch ( const Exception & ex )
+ {
+ throw( Out::Error( ZYPPER_EXIT_ERR_ZYPP, _("Check failed:"), ex ) );
+ }
+}
+
+void PSCommand::printServiceNamesOnly()
+{
+ CheckAccessDeleted checker( false ); // wait for explicit call to check()
+ loadData( checker );
+
+ std::set<std::string> services;
+ for ( const auto & procInfo : checker )
+ {
+ std::string service( procInfo.service() );
+ if ( ! service.empty() )
+ services.insert( std::move(service) );
+ }
+
+ const std::string & format( _format );
+ if ( format.empty() || format == "%s" )
+ {
+ for ( const auto & service : services )
+ { cout << service << endl; }
+ }
+ else
+ {
+ for ( const auto & service : services )
+ { cout << str::gsub( format, "%s", service ) << endl; }
+ }
+}
+
+/**
+ * fate #300763
+ * Used by 'zypper ps' to show running processes that use
+ * libraries or other files that have been removed since their execution.
+ * This is particularly useful after 'zypper remove' or 'zypper update'.
+ */
+int PSCommand::execute( Zypper &zypp, const std::vector<std::string> &positionalArgs )
+{
+ if ( !positionalArgs.empty() )
+ {
+ report_too_many_arguments( help() );
+ return ZYPPER_EXIT_ERR_INVALID_ARGS;
+ }
+
+ // implies -sss
+ if ( !_format.empty() )
+ _shortness = 3;
+
+ if ( printServiceNamesOnlyEnabled() ) {
+ // non table output of service names only
+ printServiceNamesOnly();
+ return ZYPPER_EXIT_OK;
+ }
+
+ // Here: Table output
+ zypp.out().info(_("Checking for running processes using deleted libraries..."), Out::HIGH );
+ CheckAccessDeleted checker( false ); // wait for explicit call to check()
+
+ if(debugEnabled())
+ checker.setDebugOutputFile(_debugFile);
+
+ loadData( checker );
+
+ Table t;
+ bool tableWithFiles = tableWithFilesEnabled();
+ bool tableWithNonServiceProcs = tableWithNonServiceProcsEnabled();
+ t.allowAbbrev(6);
+ {
+ TableHeader th;
+ // process ID
+ th << _("PID")
+ // parent process ID
+ << _("PPID")
+ // process user ID
+ << _("UID")
+ // process login name
+ << _("User")
+ // process command name
+ << _("Command")
+ // "/etc/init.d/ script that might be used to restart the command (guessed)
+ << _("Service");
+ if ( tableWithFiles )
+ {
+ // "list of deleted files or libraries accessed"
+ th << _("Files");
+ }
+ t << std::move(th);
+ }
+
+ for ( const auto & procInfo : checker )
+ {
+ std::string service( procInfo.service() );
+ if ( ! tableWithNonServiceProcs && service.empty() )
+ continue;
+
+ TableRow tr;
+ tr << procInfo.pid << procInfo.ppid << procInfo.puid << procInfo.login << procInfo.command << std::move(service);
+
+ if ( tableWithFiles )
+ {
+ std::vector<std::string>::const_iterator fit = procInfo.files.begin();
+ tr << (fit != procInfo.files.end() ? *fit : "");
+ t << std::move(tr);
+
+ for ( ++fit; fit != procInfo.files.end(); ++fit )
+ { t << ( TableRow() << "" << "" << "" << "" << "" << "" << *fit ); }
+ }
+ else
+ {
+ t << std::move(tr);
+ }
+ }
+
+ if ( t.empty() )
+ {
+ zypp.out().info(_("No processes using deleted files found.") );
+ }
+ else
+ {
+ zypp.out().info(_("The following running processes use deleted files:") );
+ cout << endl;
+ cout << t << endl;
+ zypp.out().info(_("You may wish to restart these processes.") );
+ zypp.out().info( str::form( _("See '%s' for information about the meaning of values in the above table."),
+ "man zypper" ) );
+ }
+
+ if ( geteuid() != 0 )
+ {
+ zypp.out().info("");
+ zypp.out().info(_("Note: Not running as root you are limited to searching for files you have permission to examine with the system stat(2) function. The result might be incomplete."));
+ }
+ return ZYPPER_EXIT_OK;
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_PS_INCLUDED
+#define ZYPPER_COMMANDS_PS_INCLUDED
+
+#include "commands/basecommand.h"
+#include "utils/flags/zyppflags.h"
+
+class PSCommand : public ZypperBaseCommand
+{
+public:
+ PSCommand( const std::vector<std::string> &commandAliases_r );
+
+ // ZypperBaseCommand interface
+ std::string description() const override;
+
+protected:
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp, const std::vector<std::string> &positionalArgs) override;
+
+ void printServiceNamesOnly();
+ bool tableWithFilesEnabled() const { return _shortness < 1; }
+ bool tableWithNonServiceProcsEnabled() const { return _shortness < 2; }
+ bool printServiceNamesOnlyEnabled() const { return _shortness >= 3; }
+ bool debugEnabled() const {return (!_debugFile.empty());}
+
+private:
+ int _shortness = 0;
+ std::string _format;
+ std::string _debugFile;
+};
+
+
+#endif
--- /dev/null
+#ifndef ZYPPER_COMMANDS_REPOS_H_INCLUDED
+#define ZYPPER_COMMANDS_REPOS_H_INCLUDED
+
+#include "repos/list.h"
+#include "repos/add.h"
+#include "repos/remove.h"
+#include "repos/rename.h"
+#include "repos/modify.h"
+#include "repos/refresh.h"
+#include "repos/clean.h"
+
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "add.h"
+#include "repos.h"
+
+#include "commands/conditions.h"
+#include "utils/flags/flagtypes.h"
+#include "utils/messages.h"
+#include "utils/misc.h"
+#include "Zypper.h"
+
+#include <zypp/repo/RepoException.h>
+
+using namespace zypp;
+
+AddRepoCmd::AddRepoCmd(const std::vector<std::string> &commandAliases_r) :
+ ZypperBaseCommand(
+ commandAliases_r,
+ std::vector<std::string>{ _("addrepo (ar) [OPTIONS] <URI> <ALIAS>"), _("addrepo (ar) [OPTIONS] <FILE.repo>") },
+ _("Add a new repository."),
+ _("Add a repository to the system. The repository can be specified by its URI or can be read from specified .repo file (even remote)."),
+ ResetRepoManager )
+{ }
+
+std::vector<BaseCommandConditionPtr> AddRepoCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
+
+zypp::ZyppFlags::CommandGroup AddRepoCmd::cmdOptions() const
+{
+ auto that = const_cast<AddRepoCmd *>(this);
+ return {{
+ { "repo", 'r', ZyppFlags::RequiredArgument, ZyppFlags::StringType( &that->_repoFile, boost::optional<const char *>(), ARG_FILE_repo), _("Just another means to specify a .repo file to read.") },
+ { "check", 'c', ZyppFlags::NoArgument, ZyppFlags::BoolType( &that->_enableCheck, ZyppFlags::StoreTrue ), _("Probe URI.") },
+ { "no-check", 'C', ZyppFlags::NoArgument, ZyppFlags::BoolType( &that->_disableCheck, ZyppFlags::StoreTrue ), _("Don't probe URI, probe later during refresh.") },
+ { "type", 't',
+ ZyppFlags::RequiredArgument | ZyppFlags::Deprecated,
+ ZyppFlags::WarnOptionVal( Zypper::instance().out(), legacyCLIStr( "type", "", LegacyCLIMsgType::Ignored ), Out::NORMAL, boost::optional<ZyppFlags::Value>() ),
+ _("The repository type is always autodetected. This option is ignored.") }
+ }};
+}
+
+void AddRepoCmd::doReset()
+{
+ _repoFile.clear();
+ _enableCheck = false;
+ _disableCheck = false;
+}
+
+int AddRepoCmd::execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r)
+{
+
+ // too many arguments
+ if ( positionalArgs_r.size() > 2 )
+ {
+ report_too_many_arguments( zypp_r.out(), help() );
+ return ( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+
+ if ( _enableCheck && _disableCheck )
+ {
+ zypp_r.out().warning(str::form(
+ _("Cannot use %s together with %s. Using the %s setting."),
+ "--check", "--no-check", "zypp.conf")
+ ,Out::QUIET );
+ }
+
+ try
+ {
+ // add repository specified in .repo file
+ if ( ! _repoFile.empty() )
+ {
+ add_repo_from_file( zypp_r, _repoFile, _commonProperties, _repoProperties, _disableCheck );
+ return zypp_r.exitCode();
+ }
+
+ switch ( positionalArgs_r.size() )
+ {
+ // display help message if insufficient info was given
+ case 0:
+ report_too_few_arguments( zypp_r.out(), help() );
+ return( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ case 1:
+ if( !isRepoFile( positionalArgs_r[0] ) )
+ {
+ zypp_r.out().error(_("If only one argument is used, it must be a URI pointing to a .repo file."));
+ ERR << "Not a repo file." << endl;
+ zypp_r.out().info( help() );
+ return ( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+ else
+ {
+ add_repo_from_file( zypp_r, positionalArgs_r[0], _commonProperties, _repoProperties, _disableCheck );
+ break;
+ }
+ case 2:
+ Url url;
+ if ( positionalArgs_r[0].find("obs") == 0 )
+ url = make_obs_url( positionalArgs_r[0], zypp_r.config().obs_baseUrl, zypp_r.config().obs_platform );
+ else
+ url = make_url( positionalArgs_r[0] );
+ if ( !url.isValid() )
+ {
+ return (ZYPPER_EXIT_ERR_INVALID_ARGS);
+ }
+
+ if ( _enableCheck )
+ zypp_r.globalOptsNoConst().rm_options.probe = true;
+ else if ( _disableCheck )
+ zypp_r.globalOptsNoConst().rm_options.probe = false;
+
+ // load gpg keys
+ int code = defaultSystemSetup( zypp_r, InitTarget );
+ if ( code != ZYPPER_EXIT_OK )
+ return code;
+
+ add_repo_by_url( zypp_r, url, positionalArgs_r[1]/*alias*/, _commonProperties, _repoProperties, _disableCheck );
+ }
+ }
+ catch ( const repo::RepoUnknownTypeException & e )
+ {
+ ZYPP_CAUGHT( e );
+ zypp_r.out().error( e, _("Specified type is not a valid repository type:"),
+ str::form( _("See '%s' or '%s' to get a list of known repository types."),
+ "zypper help addrepo", "man zypper" ) );
+ return ZYPPER_EXIT_ERR_INVALID_ARGS;
+ }
+
+
+ return zypp_r.exitCode();;
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_REPOS_ADD_H_INCLUDED
+#define ZYPPER_COMMANDS_REPOS_ADD_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "commands/reposerviceoptionsets.h"
+
+#include <zypp/TriBool.h>
+
+#include <string>
+
+class AddRepoCmd : public ZypperBaseCommand
+{
+public:
+ AddRepoCmd( const std::vector<std::string> &commandAliases_r );
+
+ // ZypperBaseCommand interface
+protected:
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r) override;
+
+private:
+ RepoProperties _repoProperties{*this};
+ RepoServiceCommonOptions _commonProperties{OptCommandCtx::RepoContext, *this};
+ std::string _repoFile;
+ bool _enableCheck = false;
+ bool _disableCheck = false;
+};
+
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "clean.h"
+
+#include "commands/conditions.h"
+#include "utils/flags/flagtypes.h"
+#include "Zypper.h"
+
+CleanRepoCmd::CleanRepoCmd( const std::vector<std::string> &commandAliases_r ):
+ ZypperBaseCommand(
+ commandAliases_r,
+ _("clean (cc) [ALIAS|#|URI] ..."),
+ _("Clean local caches."),
+ _("Clean local caches."),
+ ResetRepoManager )
+{ }
+
+std::vector<BaseCommandConditionPtr> CleanRepoCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
+
+zypp::ZyppFlags::CommandGroup CleanRepoCmd::cmdOptions() const
+{
+ auto that = const_cast<CleanRepoCmd *>(this);
+ return {{
+ {
+ "repo", 'r', ZyppFlags::RequiredArgument | ZyppFlags::Repeatable,
+ ZyppFlags::StringVectorType( &that->_repos, ARG_REOSITORY),
+ // translators: -r, --repo <ALIAS|#|URI>
+ _("Clean only specified repositories.")
+ },{
+ "metadata", 'm', ZyppFlags::NoArgument,
+ ZyppFlags::BitFieldType ( that->_flags, CleanRepoBits::CleanMetaData),
+ // translators: -m, --metadata
+ _("Clean metadata cache.")
+
+ },{
+ "raw-metadata", 'M', ZyppFlags::NoArgument,
+ ZyppFlags::BitFieldType ( that->_flags, CleanRepoBits::CleanRawMetaData),
+ // translators: -M, --raw-metadata
+ _("Clean raw metadata cache.")
+ },{
+ "all", 'a', ZyppFlags::NoArgument,
+ ZyppFlags::BitFieldType ( that->_flags, CleanRepoBits::CleanAll),
+ // translators: -a, --all
+ _("Clean both metadata and package caches.")
+ }
+ }};
+}
+
+void CleanRepoCmd::doReset()
+{
+ _repos.clear();
+ _flags = CleanRepoBits::Default;
+}
+
+int CleanRepoCmd::execute( Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r )
+{
+ // get the list of repos specified on the command line ...
+ std::vector<std::string> specifiedRepos = _repos;
+ for ( const std::string &repoFromCLI : positionalArgs_r )
+ specifiedRepos.push_back(repoFromCLI);
+
+ clean_repos( zypp_r, specifiedRepos, _flags );
+
+ return zypp_r.exitCode();
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_REPOS_CLEAN_H_INCLUDED
+#define ZYPPER_COMMANDS_REPOS_CLEAN_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "repos.h"
+
+#include <string>
+#include <vector>
+
+class CleanRepoCmd : public ZypperBaseCommand
+{
+public:
+ CleanRepoCmd( const std::vector<std::string> &commandAliases_r );
+
+ // ZypperBaseCommand interface
+protected:
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r) override;
+
+private:
+ std::vector<std::string> _repos;
+ CleanRepoFlags _flags;
+};
+
+#endif
--- /dev/null
+#include "list.h"
+#include "Zypper.h"
+#include "repos.h"
+#include "utils/messages.h"
+#include "utils/flags/flagtypes.h"
+
+#include <zypp/RepoManager.h>
+
+#include <fstream>
+
+using namespace zypp;
+
+namespace {
+
+void print_repos_to( const std::list<RepoInfo> & repos, std::ostream & out )
+{
+ for_( it, repos.begin(), repos.end() )
+ it->dumpAsIniOn( out ) << endl;
+}
+
+/** Repo list as xml */
+void print_xml_repo_list( Zypper & zypper, std::list<RepoInfo> repos )
+{
+ cout << "<repo-list>" << endl;
+ for_( it, repos.begin(), repos.end() )
+ it->dumpAsXmlOn( cout );
+ cout << "</repo-list>" << endl;
+}
+
+void print_repo_details( Zypper & zypper, std::list<RepoInfo> & repos )
+{
+ bool first = true;
+ for_( it, repos.begin(), repos.end() )
+ {
+ const RepoInfo & repo( *it );
+
+ PropertyTable p;
+ RepoGpgCheckStrings repoGpgCheck( repo );
+
+ p.add( _("Alias"), repo.alias() );
+ p.add( _("Name"), repo.name() );
+ p.add( _("URI"), (repo.baseUrlSet()
+ ? repo.url().asString()
+ : (repo.mirrorListUrl().asString().empty()
+ ? "n/a"
+ : repo.mirrorListUrl().asString())) );
+ p.add( _("Enabled"), repoGpgCheck._enabledYN.str() );
+ p.add( _("GPG Check"), repoGpgCheck._gpgCheckYN.str() );
+ p.add( _("Priority"), repoPriorityNumberAnnotated( repo.priority() ) );
+ p.add( _("Autorefresh"), (repo.autorefresh() ? _("On") : _("Off")) );
+ p.add( _("Keep Packages"), (repo.keepPackages() ? _("On") : _("Off")) );
+ p.add( _("Type"), repo.type().asString() );
+ p.add( _("GPG Key URI"), repo.gpgKeyUrl() );
+ p.add( _("Path Prefix"), repo.path() );
+ p.add( _("Parent Service"), repo.service() );
+ p.lst( _("Keywords"), repo.contentKeywords() );
+ p.add( _("Repo Info Path"), repo.filepath() );
+ p.add( _("MD Cache Path"), repo.metadataPath() );
+
+
+ if ( first )
+ first = false;
+ else
+ cout << endl;
+ cout << p;
+ }
+}
+
+}
+
+ListReposCmd::ListReposCmd(const std::vector<std::string> &commandAliases_r)
+ : ZypperBaseCommand(
+ commandAliases_r,
+ _("repos (lr) [OPTIONS] [REPO] ..."),
+ _("List all defined repositories."),
+ _("List all defined repositories."),
+ ResetRepoManager
+ )
+{ }
+
+zypp::ZyppFlags::CommandGroup ListReposCmd::cmdOptions() const
+{
+ auto that = const_cast<ListReposCmd *>(this);
+ return {{
+ { "export", 'e', ZyppFlags::RequiredArgument, ZyppFlags::StringType(&that->_exportFile, boost::optional<const char *>(), "FILE.repo"),
+ // translators: -e, --export <FILE.repo>
+ _("Export all defined repositories as a single local .repo file.") }
+ }};
+}
+
+void ListReposCmd::doReset()
+{
+ _exportFile.clear();
+}
+
+int ListReposCmd::execute( Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r )
+{
+ checkIfToRefreshPluginServices( zypp_r );
+
+ RepoManager & manager = zypp_r.repoManager();
+ RuntimeData & gData = zypp_r.runtimeData();
+ std::list<RepoInfo> repos;
+ std::list<std::string> not_found;
+
+ try
+ {
+ if ( positionalArgs_r.empty() )
+ repos.insert( repos.end(), manager.repoBegin(), manager.repoEnd() );
+ else
+ {
+ get_repos( zypp_r, positionalArgs_r.begin(),positionalArgs_r.end(), repos, not_found );
+ report_unknown_repos( zypp_r.out(), not_found );
+ }
+ }
+ catch ( const Exception & e )
+ {
+ ZYPP_CAUGHT( e );
+ zypp_r.out().error( e, _("Error reading repositories:") );
+ return ( ZYPPER_EXIT_ERR_ZYPP );
+ }
+
+ // add the temporary repos specified with the --plus-repo to the list
+ if ( !gData.temporary_repos.empty() )
+ repos.insert( repos.end(), gData.temporary_repos.begin(), gData.temporary_repos.end() );
+
+ // export to file or stdout in repo file format
+ /// \todo dedup writing code in list_services
+ if ( !_exportFile.empty() )
+ {
+ std::string filename_str = _exportFile;
+ if ( filename_str == "-" )
+ {
+ print_repos_to(repos, cout);
+ }
+ else
+ {
+ if ( filename_str.rfind(".repo") == std::string::npos )
+ filename_str += ".repo";
+
+ Pathname file( filename_str );
+ std::ofstream stream( file.c_str() );
+ if ( !stream )
+ {
+ zypp_r.out().error( str::Format(_("Can't open %s for writing.")) % file.asString(),
+ _("Maybe you do not have write permissions?") );
+ return ( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+ else
+ {
+ print_repos_to( repos, stream );
+ zypp_r.out().info( str::Format(_("Repositories have been successfully exported to %s.")) % file,
+ Out::QUIET );
+ }
+ }
+ }
+ // print repo list as xml
+ else if ( zypp_r.out().type() == Out::TYPE_XML )
+ print_xml_repo_list( zypp_r, repos );
+ else if ( !zypp_r.arguments().empty() )
+ print_repo_details( zypp_r, repos );
+ // print repo list as table
+ else
+ printRepoList( zypp_r, repos );
+
+ if ( !not_found.empty() ) {
+ return ( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ } else if ( repos.empty() ) {
+ return ( ZYPPER_EXIT_NO_REPOS );
+ }
+
+ return ZYPPER_EXIT_OK;
+}
+
+void ListReposCmd::printRepoList( Zypper & zypper, const std::list<RepoInfo> & repos )
+{
+ Table tbl;
+ bool all = _listOptions._flags.testFlag( RSCommonListOptions::ListRepoShowAll );
+ std::string list_cols = zypper.config().repo_list_columns;
+
+ bool showalias = _listOptions._flags.testFlag( RSCommonListOptions::ShowAlias )
+ || list_cols.find_first_of("aA") != std::string::npos;
+ bool showname = _listOptions._flags.testFlag( RSCommonListOptions::ShowName )
+ || list_cols.find_first_of("nN") != std::string::npos;
+ bool showrefresh = _listOptions._flags.testFlag( RSCommonListOptions::ShowRefresh )
+ || list_cols.find_first_of("rR") != std::string::npos;
+ bool showuri = _listOptions._flags.testFlag( RSCommonListOptions::ShowURI )
+ || list_cols.find_first_of("uU") != std::string::npos;
+ bool showprio = _listOptions._flags.testFlag( RSCommonListOptions::ShowPriority )
+ || list_cols.find_first_of("pP") != std::string::npos;
+ bool showservice = _listOptions._flags.testFlag( RSCommonListOptions::ShowWithService );
+ bool sort_override = _listOptions._flags.testFlag( RSCommonListOptions::SortByURI )
+ || _listOptions._flags.testFlag( RSCommonListOptions::SortByPrio )
+ || _listOptions._flags.testFlag( RSCommonListOptions::SortByAlias )
+ || _listOptions._flags.testFlag( RSCommonListOptions::SortByName );
+ bool show_enabled_only = _listOptions._flags.testFlag( RSCommonListOptions::ShowEnabledOnly );
+
+
+ // header
+ TableHeader th;
+ // keep count of columns so that we know which one to sort
+ // TODO might be worth to improve Table to allow named columns so this can be avoided
+ unsigned index = 0;
+ // number of the column to sort by
+ unsigned sort_index = 0;
+
+ // repo number
+ th << "#";
+
+ // alias
+ if ( all || showalias )
+ {
+ th << _("Alias");
+ ++index;
+ // if (zypper.cOpts().count("sort-by-alias")
+ // || (list_cols.find("A") != std::string::npos && !sort_override))
+ // sort by alias by default
+ sort_index = index;
+ }
+
+ // name
+ if ( all || showname )
+ {
+ th << _("Name");
+ ++index;
+ if ( _listOptions._flags.testFlag( RSCommonListOptions::SortByName ) || ( list_cols.find("N") != std::string::npos && !sort_override ) )
+ sort_index = index;
+ }
+
+ // 'enabled' flag
+ th << _("Enabled");
+ ++index;
+
+ // GPG Check
+ th << _("GPG Check");
+ ++index;
+
+ // 'autorefresh' flag
+ if ( all || showrefresh )
+ {
+ // translators: 'zypper repos' column - whether autorefresh is enabled
+ // for the repository
+ th << _("Refresh");
+ ++index;
+ if ( list_cols.find("R") != std::string::npos && !sort_override )
+ sort_index = index;
+ }
+
+ // priority
+ if ( all || showprio )
+ {
+ // translators: repository priority (in zypper repos -p or -d)
+ th << _("Priority");
+ ++index;
+ if ( _listOptions._flags.testFlag( RSCommonListOptions::SortByPrio ) || ( list_cols.find("P") != std::string::npos && !sort_override ) )
+ sort_index = Table::UserData;
+ }
+
+ // type
+ if ( all )
+ {
+ th << _("Type");
+ ++index;
+ }
+
+ // URI
+ if ( all || showuri )
+ {
+ th << _("URI");
+ ++index;
+ if ( _listOptions._flags.testFlag( RSCommonListOptions::SortByURI ) || ( list_cols.find("U") != std::string::npos && !sort_override ) )
+ sort_index = index;
+ }
+
+ // service alias
+ if ( all || showservice )
+ {
+ th << _("Service");
+ ++index;
+ }
+
+ tbl << th;
+
+ // table data
+ int i = 0;
+ unsigned nindent = repos.size() > 9 ? repos.size() > 99 ? 3 : 2 : 1;
+ for_( it, repos.begin(), repos.end() )
+ {
+ ++i; // continuous numbering including skipped ones
+ RepoInfo repo = *it;
+
+ if ( show_enabled_only && !repo.enabled() )
+ continue;
+
+ TableRow tr( index );
+ RepoGpgCheckStrings repoGpgCheck( repo ); // color strings for tag/enabled/gpgcheck
+
+ // number
+ tr << ColorString( repoGpgCheck._tagColor, str::numstring( i, nindent ) ).str();
+ // alias
+ if ( all || showalias ) tr << repo.alias();
+ // name
+ if ( all || showname ) tr << repo.name();
+ // enabled?
+ tr << repoGpgCheck._enabledYN.str();
+ // GPG Check
+ tr << repoGpgCheck._gpgCheckYN.str();
+ // autorefresh?
+ if ( all || showrefresh )
+ tr << repoAutorefreshStr( repo );
+ // priority
+ if ( all || showprio )
+ // output flush right; use custom sort index as coloring will break lex. sort
+ ( tr << repoPriorityNumber( repo.priority(), 4 ) ).userData( repo.priority() );
+ // type
+ if ( all )
+ tr << repo.type().asString();
+ // url
+ /**
+ * \todo properly handle multiple baseurls - show "(multiple)"
+ */
+ if ( all || showuri )
+ tr << (repo.baseUrlSet() ? repo.url().asString() : (repo.mirrorListUrl().asString().empty() ? "n/a" : repo.mirrorListUrl().asString()) );
+
+ if ( all || showservice )
+ tr << repo.service();
+
+ tbl << tr;
+ }
+
+ if ( tbl.empty() )
+ {
+ zypper.out().warning(_("No repositories defined.") );
+ zypper.out().info(_("Use the 'zypper addrepo' command to add one or more repositories.") );
+ }
+ else
+ {
+ if ( !showprio )
+ {
+ repoPrioSummary( zypper );
+ zypper.out().gap();
+ }
+ // sort
+ tbl.sort( sort_index );
+ // print
+ cout << tbl;
+ }
+}
+
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_REPOS_LIST_H_INCLUDED
+#define ZYPPER_COMMANDS_REPOS_LIST_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "commands/reposerviceoptionsets.h"
+#include "utils/flags/zyppflags.h"
+
+#include <zypp/base/Flags.h>
+#include <zypp/RepoInfo.h>
+
+class ListReposCmd : public ZypperBaseCommand
+{
+public:
+ ListReposCmd( const std::vector<std::string> &commandAliases_r );
+
+ // ZypperBaseCommand interface
+protected:
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r) override;
+ void printRepoList(Zypper &zypper, const std::list<zypp::RepoInfo> &repos);
+
+private:
+ std::string _exportFile;
+ RSCommonListOptions _listOptions{ OptCommandCtx::RepoContext, *this };
+};
+
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "modify.h"
+#include "repos.h"
+
+#include "commands/conditions.h"
+#include "commands/commandhelpformatter.h"
+
+#include "utils/messages.h"
+#include "utils/flags/flagtypes.h"
+
+using namespace zypp;
+
+
+ModifyRepoCmd::ModifyRepoCmd(const std::vector<std::string> &commandAliases_r) :
+ ZypperBaseCommand (
+ commandAliases_r,
+ {
+ // translators: command synopsis; do not translate lowercase words
+ _("modifyrepo (mr) <OPTIONS> <ALIAS|#|URI>"),
+ // translators: command synopsis; do not translate lowercase words
+ str::Format( _("modifyrepo (mr) <OPTIONS> <%1%>") ) % "--all|--remote|--local|--medium-type"
+ },
+ // translators: command summary
+ _("Modify specified repository."),
+ // translators: command description
+ str::Format( _("Modify properties of repositories specified by alias, number, or URI, or by the '%1%' aggregate options.") ) % "--all, --remote, --local, --medium-type",
+ ResetRepoManager
+ )
+{ }
+
+std::vector<BaseCommandConditionPtr> ModifyRepoCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
+
+zypp::ZyppFlags::CommandGroup ModifyRepoCmd::cmdOptions() const
+{
+ auto that = const_cast<ModifyRepoCmd *>(this);
+ return {{
+ //some legacy options
+ {"legacy-refresh", 'r', ZyppFlags::NoArgument | ZyppFlags::Hidden, ZyppFlags::TriBoolType( that->_commonProps._enableAutoRefresh, ZyppFlags::StoreTrue ), "" },
+ {"legacy-no-refresh", 'R', ZyppFlags::NoArgument | ZyppFlags::Hidden, ZyppFlags::TriBoolType( that->_commonProps._enableAutoRefresh, ZyppFlags::StoreFalse), "" }
+ }};
+}
+
+void ModifyRepoCmd::doReset()
+{ }
+
+int ModifyRepoCmd::execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r )
+{
+ bool aggregate = _selections._all || _selections._local || _selections._remote || _selections._mediumTypes.size();
+
+ if ( positionalArgs_r.size() < 1 && !aggregate )
+ {
+ report_alias_or_aggregate_required (zypp_r.out(), help() );
+ ERR << "No alias argument given." << endl;
+ return ( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+
+ // too many arguments
+ if ( positionalArgs_r.size() && aggregate )
+ {
+ report_too_many_arguments( help() );
+ return ( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+
+ if ( aggregate )
+ {
+ modify_repos_by_option( zypp_r, _selections, _commonProps, _repoProps );
+ }
+ else
+ {
+ for_( arg,positionalArgs_r.begin(),positionalArgs_r.end() )
+ {
+ RepoInfo r;
+ if ( match_repo(zypp_r,*arg,&r) )
+ {
+ modify_repo( zypp_r, r.alias(), _commonProps, _repoProps );
+ }
+ else
+ {
+ zypp_r.out().error( str::Format(_("Repository %s not found.")) % *arg );
+ ERR << "Repo " << *arg << " not found" << endl;
+ return ( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+ }
+ }
+
+ return ZYPPER_EXIT_OK;
+}
+
+
+std::string ModifyRepoCmd::help()
+{
+ CommandHelpFormater formatter;
+
+ formatter << ZypperBaseCommand::help();
+
+ formatter
+ .legacyOptionSection()
+ .legacyOption( "-r", "-f" )
+ .legacyOption( "-R", "-F" );
+
+ return formatter;
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_REPOS_MODIFY_H_INCLUDED
+#define ZYPPER_COMMANDS_REPOS_MODIFY_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "commands/reposerviceoptionsets.h"
+
+class ModifyRepoCmd : public ZypperBaseCommand
+{
+public:
+ ModifyRepoCmd( const std::vector<std::string> &commandAliases_r );
+
+ // ZypperBaseCommand interface
+ std::string help() override;
+
+protected:
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r) override;
+
+private:
+ RepoServiceCommonOptions _commonProps{OptCommandCtx::RepoContext, *this};
+ RepoProperties _repoProps{*this};
+ RepoServiceCommonSelectOptions _selections{OptCommandCtx::RepoContext, *this};
+};
+
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "refresh.h"
+#include "repos.h"
+#include "commands/conditions.h"
+#include "commands/services/refresh.h"
+
+
+#include "utils/messages.h"
+#include "utils/flags/flagtypes.h"
+#include "Zypper.h"
+
+using namespace zypp;
+
+extern ZYpp::Ptr God;
+
+RefreshRepoCmd::RefreshRepoCmd( const std::vector<std::string> &commandAliases_r )
+ : ZypperBaseCommand (
+ commandAliases_r,
+ _("refresh (ref) [ALIAS|#|URI] ..."),
+ // translators: command summary: refresh, ref
+ _("Refresh all repositories."),
+ // translators: command description
+ _("Refresh repositories specified by their alias, number or URI. If none are specified, all enabled repositories will be refreshed."),
+ ResetRepoManager
+ )
+{
+
+}
+
+std::vector<BaseCommandConditionPtr> RefreshRepoCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
+
+zypp::ZyppFlags::CommandGroup RefreshRepoCmd::cmdOptions() const
+{
+ auto that = const_cast<RefreshRepoCmd *>(this);
+ return {{
+ {"force",'f', ZyppFlags::NoArgument,
+ ZyppFlags::BitFieldType( that->_flags, Force ),
+ // translators: -f, --force
+ _("Force a complete refresh.")
+ },
+ {"force-build", 'b', ZyppFlags::NoArgument,
+ ZyppFlags::BitFieldType( that->_flags, ForceBuild ),
+ // translators: -b, --force-build
+ _("Force rebuild of the database.")
+ },
+ {"force-download", 'd', ZyppFlags::NoArgument,
+ ZyppFlags::BitFieldType( that->_flags, ForceDownload ),
+ // translators: -d, --force-download
+ _("Force download of raw metadata.")
+ },
+ {"build-only", 'B', ZyppFlags::NoArgument,
+ ZyppFlags::BitFieldType( that->_flags, BuildOnly ),
+ // translators: -B, --build-only
+ _("Only build the database, don't download metadata.")
+ },
+ {"download-only", 'D', ZyppFlags::NoArgument,
+ ZyppFlags::BitFieldType( that->_flags, DownloadOnly ),
+ // translators: -D, --download-only
+ _("Only download raw metadata, don't build the database.")
+ },
+ {"repo", 'r', ZyppFlags::RequiredArgument | ZyppFlags::Repeatable,
+ ZyppFlags::StringVectorType( &that->_repos, ARG_REOSITORY),
+ // translators: -r, --repo <ALIAS|#|URI>
+ _("Refresh only specified repositories.")
+ }
+ ,
+ {"services", 's', ZyppFlags::NoArgument,
+ ZyppFlags::BoolType( &that->_services, ZyppFlags::StoreTrue, false ),
+ // translators: -s, --services
+ _("Refresh also services before refreshing repos.")
+ },
+ }};
+}
+
+void RefreshRepoCmd::doReset()
+{
+ _flags = Default;
+ _repos.clear();
+ _services = false;
+}
+
+int RefreshRepoCmd::execute( Zypper &zypp_r , const std::vector<std::string> &positionalArgs_r )
+{
+ if ( zypp_r.globalOpts().no_refresh )
+ zypp_r.out().warning( str::Format(_("The '%s' global option has no effect here.")) % "--no-refresh" );
+
+ bool force = _flags.testFlag(Force);
+
+ if ( _services )
+ {
+ if ( !positionalArgs_r.empty() )
+ {
+ zypp_r.out().error(str::form(_("Arguments are not allowed if '%s' is used."), "--services"));
+ return ( ZYPPER_EXIT_ERR_PRIVILEGES );
+ }
+
+ RefreshServicesCmd refServiceCmd( {} );
+ refServiceCmd.setForce( force );
+ refServiceCmd.setRestoreStatus( false );
+ refServiceCmd.setWithRepos( false );
+
+ // needed to be able to retrieve target distribution
+ int code = defaultSystemSetup ( zypp_r, InitTarget );
+ if ( code != ZYPPER_EXIT_OK )
+ return code;
+
+ zypp_r.globalOptsNoConst().rm_options.servicesTargetDistro = God->target()->targetDistribution();
+
+ code = refServiceCmd.refreshServices( zypp_r );
+ if ( code != ZYPPER_EXIT_OK )
+ return code;
+ }
+ else
+ {
+ RepoManager::RefreshServiceOptions opts;
+ if ( force )
+ opts |= RepoManager::RefreshService_forceRefresh;
+
+ checkIfToRefreshPluginServices( zypp_r, opts );
+ }
+
+ MIL << "going to refresh repositories" << endl;
+ // need gpg keys when downloading (#304672)
+ int code = defaultSystemSetup ( zypp_r, InitTarget );
+ if ( code != ZYPPER_EXIT_OK )
+ return code;
+
+ std::vector<std::string> specifiedRepos = _repos;
+ for ( const std::string &repoFromCLI : positionalArgs_r )
+ specifiedRepos.push_back(repoFromCLI);
+
+ return refreshRepositories ( zypp_r, _flags, specifiedRepos );
+}
+
+bool RefreshRepoCmd::refreshRepository(Zypper &zypper, const RepoInfo &repo, RefreshFlags flags_r)
+{
+ MIL << "going to refresh repo '" << repo.alias() << "'" << endl;
+
+ // raw metadata refresh
+ bool error = false;
+ if ( !flags_r.testFlag(BuildOnly) )
+ {
+ bool force_download = flags_r.testFlag(Force) || flags_r.testFlag(ForceDownload);
+ MIL << "calling refreshMetadata" << (force_download ? ", forced" : "") << endl;
+ error = refresh_raw_metadata( zypper, repo, force_download );
+ }
+
+ // db rebuild
+ if ( !( error || flags_r.testFlag(DownloadOnly) ) )
+ {
+ bool force_build = flags_r.testFlag(Force) || flags_r.testFlag(ForceBuild);;
+ MIL << "calling buildCache" << (force_build ? ", forced" : "") << endl;
+ error = build_cache( zypper, repo, force_build );
+ }
+
+ return error;
+}
+
+int RefreshRepoCmd::refreshRepositories( Zypper &zypp_r, RefreshFlags flags_r, const std::vector<std::string> repos_r )
+{
+ RepoManager & manager( zypp_r.repoManager() );
+ const std::list<RepoInfo> & repos( manager.knownRepositories() );
+
+ // get the list of repos specified on the command line ...
+ std::list<RepoInfo> specified;
+ std::list<std::string> not_found;
+ get_repos( zypp_r, repos_r.begin(),repos_r.end(), specified, not_found );
+ report_unknown_repos( zypp_r.out(), not_found );
+
+ // --plus-content: It either specifies a known repo (by #, alias or URL)
+ // or we need to also refresh all disabled repos to get their content
+ // keywords.
+ std::set<RepoInfo> plusContent;
+ bool doContentCheck = false;
+ for ( const std::string & spec : zypp_r.runtimeData().plusContentRepos )
+ {
+ RepoInfo r;
+ if ( match_repo( zypp_r, spec, &r ) )
+ plusContent.insert( r ); // specific repo: add to plusContent
+ else if ( ! doContentCheck )
+ doContentCheck = true; // keyword: need to scan all disabled repos
+ }
+
+ std::ostringstream s;
+ s << _("Specified repositories: ");
+ for_( it, specified.begin(), specified.end() )
+ s << it->alias() << " ";
+ zypp_r.out().info( s.str(), Out::HIGH );
+
+ unsigned error_count = 0;
+ unsigned enabled_repo_count = repos.size();
+
+ if ( !specified.empty() || not_found.empty() )
+ {
+ for_( rit, repos.begin(), repos.end() )
+ {
+ const RepoInfo & repo( *rit );
+
+ if ( repo.enabled() )
+ {
+ // enabled: Refreshed unless restricted by CLI args or mentioned in
+ // --plus-content as specific repo.
+ if ( !specified.empty() && std::find( specified.begin(), specified.end(), repo ) == specified.end() )
+ {
+ if ( plusContent.count( repo ) )
+ {
+ MIL << "[--plus-content] check " << repo.alias() << endl;
+ zypp_r.out().info( str::Format(_("Refreshing repository '%s'.")) % repo.asUserString(),
+ " [--plus-content]" );
+ }
+ else
+ {
+ DBG << repo.alias() << "(#" << ") not specified," << " skipping." << endl;
+ enabled_repo_count--;
+ continue;
+ }
+ }
+ }
+ else
+ {
+ // disabled: No refresh unless mentioned in --plus-content (specific or content check).
+ // CLI args reffering to disabled repos are reported as error.
+ if ( doContentCheck || plusContent.count( repo ) )
+ {
+ MIL << "[--plus-content] check " << repo.alias() << endl;
+ zypp_r.out().info( str::Format(_("Scanning content of disabled repository '%s'.")) % repo.asUserString(),
+ " [--plus-content]" );
+ }
+ else
+ {
+ if ( !specified.empty() && std::find( specified.begin(), specified.end(), repo ) == specified.end() )
+ {
+ DBG << repo.alias() << "(#" << ") not specified," << " skipping." << endl;
+ }
+ else
+ {
+ std::string msg( str::Format(_("Skipping disabled repository '%s'")) % repo.asUserString() );
+
+ if ( specified.empty() )
+ zypp_r.out().info( msg, Out::HIGH );
+ else
+ zypp_r.out().error( msg );
+ }
+ enabled_repo_count--;
+ continue;
+ }
+ }
+
+ // do the refresh
+ if ( refreshRepository( zypp_r, repo, flags_r ) )
+ {
+ zypp_r.out().error( str::Format(_("Skipping repository '%s' because of the above error.")) % repo.asUserString() );
+ ERR << "Skipping repository '" << repo.alias() << "' because of the above error." << endl;
+ error_count++;
+ }
+ }
+ }
+ else
+ enabled_repo_count = 0;
+
+ // print the result message
+ if ( !not_found.empty() )
+ {
+ zypp_r.out().error(_("Some of the repositories have not been refreshed because they were not known.") );
+ return ZYPPER_EXIT_ERR_INVALID_ARGS;
+ }
+ else if ( enabled_repo_count == 0 )
+ {
+ int code = ZYPPER_EXIT_OK;
+ if ( !specified.empty() )
+ zypp_r.out().warning(_("Specified repositories are not enabled or defined.") );
+ else {
+ zypp_r.out().warning(_("There are no enabled repositories defined.") );
+ code = ( ZYPPER_EXIT_NO_REPOS );
+ }
+
+ zypp_r.out().info( str::form(_("Use '%s' or '%s' commands to add or enable repositories."),
+ "zypper addrepo", "zypper modifyrepo" ) );
+ return code;
+ }
+ else if ( error_count == enabled_repo_count )
+ {
+ zypp_r.out().error(_("Could not refresh the repositories because of errors.") );
+ return ( ZYPPER_EXIT_ERR_ZYPP );
+ }
+ else if ( error_count )
+ {
+ zypp_r.out().error(_("Some of the repositories have not been refreshed because of an error.") );
+ return ( ZYPPER_EXIT_ERR_ZYPP );
+ }
+ else if ( !specified.empty() )
+ zypp_r.out().info(_("Specified repositories have been refreshed.") );
+ else
+ zypp_r.out().info(_("All repositories have been refreshed.") );
+
+ return ZYPPER_EXIT_OK;
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_REPOS_REFRESH_H_INCLUDED
+#define ZYPPER_COMMANDS_REPOS_REFRESH_H_INCLUDED
+
+#include "commands/basecommand.h"
+
+#include <zypp/base/Flags.h>
+
+class RefreshRepoCmd : public ZypperBaseCommand
+{
+public:
+
+ enum RefreshFlagsBits {
+ Default = 0,
+ Force = 1,
+ ForceBuild = 1 << 1,
+ ForceDownload = 1 << 2,
+ BuildOnly = 1 << 3,
+ DownloadOnly = 1 << 4
+ };
+ ZYPP_DECLARE_FLAGS(RefreshFlags,RefreshFlagsBits);
+
+ RefreshRepoCmd( const std::vector<std::string> &commandAliases_r );
+
+ static int refreshRepositories ( Zypper &zypp_r, RefreshFlags flags_r = Default, const std::vector<std::string> repos_r = std::vector<std::string>() );
+
+ /** \return false on success, true on error */
+ static bool refreshRepository ( Zypper & zypper, const zypp::RepoInfo & repo, RefreshFlags flags_r = Default );
+
+ // ZypperBaseCommand interface
+protected:
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs) override;
+
+
+private:
+ RefreshFlags _flags;
+ std::vector<std::string> _repos;
+ bool _services = false;
+};
+ZYPP_DECLARE_OPERATORS_FOR_FLAGS(RefreshRepoCmd::RefreshFlags);
+
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "remove.h"
+#include "repos.h"
+
+#include "commands/conditions.h"
+#include "utils/flags/flagtypes.h"
+#include "utils/messages.h"
+#include "utils/misc.h"
+#include "Zypper.h"
+
+using namespace zypp;
+
+RemoveRepoCmd::RemoveRepoCmd( const std::vector<std::string> &commandAliases_r ) :
+ ZypperBaseCommand (
+ commandAliases_r,
+ _("removerepo (rr) [OPTIONS] <ALIAS|#|URI>"),
+ _("Remove specified repository."),
+ _("Remove repository specified by alias, number or URI."),
+ ResetRepoManager
+ )
+{
+
+}
+
+std::vector<BaseCommandConditionPtr> RemoveRepoCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
+
+zypp::ZyppFlags::CommandGroup RemoveRepoCmd::cmdOptions() const
+{
+ //@TODO merge into a OptionSet to share with RemoveServiceCommand ?
+ auto that = const_cast<RemoveRepoCmd *>(this);
+ return {{{
+ { "loose-auth", '\0', ZyppFlags::NoArgument, ZyppFlags::BoolType( &that->_looseAuth, ZyppFlags::StoreTrue),
+ // translators: --loose-auth
+ _("Ignore user authentication data in the URI.")
+ },{ "loose-query", '\0', ZyppFlags::NoArgument, ZyppFlags::BoolType( &that->_looseQuery, ZyppFlags::StoreTrue),
+ // translators: --loose-query
+ _("Ignore query string in the URI.")
+ }
+ }}};
+}
+
+void RemoveRepoCmd::doReset()
+{
+ _looseAuth = false;
+ _looseQuery = false;
+}
+
+int RemoveRepoCmd::execute( Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r )
+{
+ bool aggregate = _selections._all || _selections._local || _selections._remote || _selections._mediumTypes.size();
+
+ if ( positionalArgs_r.size() < 1 && !aggregate )
+ {
+ report_alias_or_aggregate_required ( zypp_r.out(), help() );
+ ERR << "No alias argument given." << endl;
+ return( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+
+ // too many arguments
+ if ( positionalArgs_r.size() && aggregate )
+ {
+ report_too_many_arguments( zypp_r.out(), help() );
+ return ( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+
+ if ( aggregate )
+ {
+ remove_repos_by_option( zypp_r, _selections );
+ }
+ else
+ {
+ // must store repository before remove to ensure correct match number
+ std::set<RepoInfo,RepoInfoAliasComparator> repo_to_remove;
+ for_(it, positionalArgs_r.begin(), positionalArgs_r.end())
+ {
+ RepoInfo repo;
+ if ( match_repo( zypp_r ,*it,&repo, _looseQuery, _looseAuth ) )
+ {
+ repo_to_remove.insert(repo);
+ }
+ else
+ {
+ MIL << "Repository not found by given alias, number or URI." << endl;
+ // translators: %s is the supplied command line argument which
+ // for which no repository counterpart was found
+ zypp_r.out().error( str::Format(_("Repository '%s' not found by alias, number or URI.")) % *it );
+ }
+ }
+
+ for_(it, repo_to_remove.begin(), repo_to_remove.end())
+ remove_repo( zypp_r, *it );
+ }
+
+ return ZYPPER_EXIT_OK;
+}
+
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_REPOS_REMOVE_H_INCLUDED
+#define ZYPPER_COMMANDS_REPOS_REMOVE_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "commands/reposerviceoptionsets.h"
+
+#include <zypp/TriBool.h>
+
+#include <string>
+
+class RemoveRepoCmd : public ZypperBaseCommand
+{
+public:
+ RemoveRepoCmd( const std::vector<std::string> &commandAliases_r );
+
+ // ZypperBaseCommand interface
+protected:
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp, const std::vector<std::string> &positionalArgs) override;
+
+private:
+ bool _looseAuth = false;
+ bool _looseQuery = false;
+ RepoServiceCommonSelectOptions _selections{OptCommandCtx::RepoContext, *this};
+};
+
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "rename.h"
+#include "repos.h"
+
+#include "commands/conditions.h"
+#include "utils/messages.h"
+
+#include "Zypper.h"
+
+using namespace zypp;
+
+namespace {
+
+/**
+ * Rename repository specified by \a alias to \a newalias.
+ */
+int rename_repo( Zypper & zypper, const std::string & alias, const std::string & newalias )
+{
+ RepoManager & manager( zypper.repoManager() );
+
+ try
+ {
+ RepoInfo repo( manager.getRepositoryInfo( alias ) );
+
+ if ( !repo.service().empty() )
+ {
+ zypper.out().error(str::form(
+ _("Cannot change alias of '%s' repository. The repository"
+ " belongs to service '%s' which is responsible for setting its alias."),
+ alias.c_str(), repo.service().c_str()));
+ return ZYPPER_EXIT_ERR_ZYPP;
+ }
+
+ repo.setAlias( newalias );
+ manager.modifyRepository( alias, repo );
+
+ MIL << "Repository '" << alias << "' renamed to '" << repo.alias() << "'" << endl;
+ zypper.out().info( str::Format(_("Repository '%s' renamed to '%s'.")) % alias % repo.alias() );
+ }
+ catch ( const repo::RepoAlreadyExistsException & ex )
+ {
+ zypper.out().error( str::Format(_("Repository named '%s' already exists. Please use another alias.")) % newalias );
+ }
+ catch ( const Exception & ex )
+ {
+ ERR << "Error while modifying the repository " << ex.asUserString() << endl;
+ zypper.out().error( ex, _("Error while modifying the repository:"),
+ str::Format(_("Leaving repository '%s' unchanged.")) % alias );
+ }
+ return ZYPPER_EXIT_OK;
+}
+
+}
+
+RenameRepoCmd::RenameRepoCmd(const std::vector<std::string> &commandAliases_r) :
+ ZypperBaseCommand (
+ commandAliases_r,
+ // translators: command synopsis; do not translate lowercase words
+ _("renamerepo (nr) [OPTIONS] <ALIAS|#|URI> <NEW-ALIAS>"),
+ _("Rename specified repository."),
+ // translators: command description
+ _("Assign new alias to the repository specified by alias, number or URI."),
+ ResetRepoManager
+ )
+{ }
+
+std::vector<BaseCommandConditionPtr> RenameRepoCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
+
+zypp::ZyppFlags::CommandGroup RenameRepoCmd::cmdOptions() const
+{
+ return {};
+}
+
+void RenameRepoCmd::doReset()
+{ }
+
+int RenameRepoCmd::execute( Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r )
+{
+
+ if ( positionalArgs_r.size() < 2 )
+ {
+ zypp_r.out().error(_("Too few arguments. At least URI and alias are required.") );
+ ERR << "Too few arguments. At least URI and alias are required." << endl;
+ zypp_r.out().info( help() );
+ return ( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+ // too many arguments
+ else if ( positionalArgs_r.size() > 2 )
+ {
+ report_too_many_arguments( help() );
+ return ( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+
+ try
+ {
+ RepoInfo repo;
+ if ( match_repo( zypp_r,positionalArgs_r[0], &repo ))
+ {
+ int code = rename_repo( zypp_r, repo.alias(), positionalArgs_r[1] );
+ return code;
+ }
+ else
+ {
+ zypp_r.out().error( str::Format(_("Repository '%s' not found.")) % positionalArgs_r[0] );
+ ERR << "Repo " << positionalArgs_r[0] << " not found" << endl;
+ }
+ }
+ catch ( const Exception & excpt_r )
+ {
+ zypp_r.out().error( excpt_r.asUserString() );
+ return ( ZYPPER_EXIT_ERR_ZYPP );
+ }
+
+ return ZYPPER_EXIT_OK;
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_REPOS_RENAME_H_INCLUDED
+#define ZYPPER_COMMANDS_REPOS_RENAME_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "commands/reposerviceoptionsets.h"
+
+#include <zypp/TriBool.h>
+
+#include <string>
+
+class RenameRepoCmd : public ZypperBaseCommand
+{
+public:
+ RenameRepoCmd( const std::vector<std::string> &commandAliases_r );
+
+ // ZypperBaseCommand interface
+protected:
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r) override;
+};
+
+#endif
--- /dev/null
+#include "reposerviceoptionsets.h"
+#include "utils/flags/flagtypes.h"
+#include "utils/flags/zyppflags.h"
+#include "src/repos.h"
+#include "main.h"
+
+#include "utils/getopt.h"
+#include "Zypper.h"
+
+using namespace zypp;
+
+namespace {
+ZyppFlags::Value PriorityType(unsigned &target, const boost::optional<unsigned> &defValue)
+{
+ return ZyppFlags::Value (
+ [defValue]() -> boost::optional<std::string>{
+ if(defValue) {
+ return std::to_string(*defValue);
+ } else
+ return boost::optional<std::string>();
+ },
+
+ [&target]( const ZyppFlags::CommandOption &opt, const boost::optional<std::string> &in ) {
+ if (!in)
+ ZYPP_THROW(ZyppFlags::MissingArgumentException(opt.name));
+
+ int prio = -1;
+ safe_lexical_cast( *in, prio ); // try to make an int out of the string
+
+ if ( prio < 0 )
+ {
+ ZYPP_THROW(ZyppFlags::InvalidValueException(
+ opt.name,
+ *in,
+ str::Format(_("Invalid priority '%s'. Use a positive integer number. The greater the number, the lower the priority.")) % *in));
+ }
+
+ target = ( prio ? unsigned(prio) : RepoInfo::defaultPriority() );
+ },
+ "PRIORITY"
+ );
+}
+
+ZyppFlags::Value GPGCheckType(RepoInfo::GpgCheck &target, RepoInfo::GpgCheck valueIfSeen)
+{
+ return ZyppFlags::Value (
+ ZyppFlags::noDefaultValue,
+ [&target, valueIfSeen]( const ZyppFlags::CommandOption &, const boost::optional<std::string> & ) {
+ target = valueIfSeen;
+ }
+ );
+}
+
+}
+
+RepoServiceCommonOptions::RepoServiceCommonOptions(OptCommandCtx ctx)
+ : _cmdContext(ctx)
+{ }
+
+RepoServiceCommonOptions::RepoServiceCommonOptions(OptCommandCtx ctx, ZypperBaseCommand &parent)
+ : BaseCommandOptionSet(parent),
+ _cmdContext(ctx)
+{ }
+
+std::vector<ZyppFlags::CommandGroup> RepoServiceCommonOptions::options()
+{
+ return {
+ {
+ {
+ {"name", 'n', ZyppFlags::RequiredArgument, ZyppFlags::StringType( &_name, boost::optional<const char *>(), "NAME"),
+ _cmdContext == OptCommandCtx::ServiceContext ? _("Set a descriptive name for the service.") : _("Set a descriptive name for the repository.")
+ },
+ {"enable", 'e', ZyppFlags::NoArgument, ZyppFlags::TriBoolType( _enable, ZyppFlags::StoreTrue, TriBool( true ) ),
+ _cmdContext == OptCommandCtx::ServiceContext ? _("Enable a disabled service.") : _("Enable a disabled repository.")
+ },
+ {"disable", 'd', ZyppFlags::NoArgument, ZyppFlags::TriBoolType(_enable, ZyppFlags::StoreFalse, TriBool( false ) ),
+ _cmdContext == OptCommandCtx::ServiceContext ? _("Disable the service (but don't remove it).") : _("Disable the repository (but don't remove it).")
+ },
+ {"refresh", 'f', ZyppFlags::NoArgument, ZyppFlags::TriBoolType( _enableAutoRefresh, ZyppFlags::StoreTrue, TriBool( true ) ),
+ _cmdContext == OptCommandCtx::ServiceContext ? _("Enable auto-refresh of the service.") : _("Enable auto-refresh of the repository.")
+ },
+ {"no-refresh", 'F', ZyppFlags::NoArgument, ZyppFlags::TriBoolType( _enableAutoRefresh, ZyppFlags::StoreFalse, TriBool( false ) ),
+ _cmdContext == OptCommandCtx::ServiceContext ? _("Disable auto-refresh of the service.") : _("Disable auto-refresh of the repository.")
+ }
+ }
+ }
+ };
+}
+
+void RepoServiceCommonOptions::reset()
+{
+ _name.clear();
+ _enable = indeterminate;
+ _enableAutoRefresh = indeterminate;
+}
+
+void RepoServiceCommonOptions::fillFromCopts( Zypper &zypper )
+{
+ reset();
+ parsed_opts::const_iterator it = zypper.cOpts().find("name");
+ if ( it != zypper.cOpts().end() )
+ _name = it->second.front();
+
+ _enable = get_boolean_option( zypper, "enable", "disable" );
+ _enableAutoRefresh = get_boolean_option( zypper, "refresh", "no-refresh" );
+}
+
+RepoServiceCommonSelectOptions::RepoServiceCommonSelectOptions(OptCommandCtx ctx)
+ : _cmdContext(ctx)
+{ }
+
+RepoServiceCommonSelectOptions::RepoServiceCommonSelectOptions(OptCommandCtx ctx, ZypperBaseCommand &parent)
+ : BaseCommandOptionSet(parent),
+ _cmdContext(ctx)
+{ }
+
+std::vector<ZyppFlags::CommandGroup> RepoServiceCommonSelectOptions::options()
+{
+ return {{{
+ {"all", 'a', ZyppFlags::NoArgument, ZyppFlags::BoolType( &_all, ZyppFlags::StoreTrue, _all),
+ _cmdContext == OptCommandCtx::ServiceContext ? _("Apply changes to all services.") : _("Apply changes to all repositories.")
+ },
+ {"local", 'l', ZyppFlags::NoArgument, ZyppFlags::BoolType( &_local, ZyppFlags::StoreTrue, _local),
+ _cmdContext == OptCommandCtx::ServiceContext ? _("Apply changes to all local services.") : _("Apply changes to all local repositories.")
+ },
+ {"remote", 't', ZyppFlags::NoArgument, ZyppFlags::BoolType( &_remote, ZyppFlags::StoreTrue, _remote),
+ _cmdContext == OptCommandCtx::ServiceContext ? _("Apply changes to all remote services.") : _("Apply changes to all remote repositories.")
+ },
+ {"medium-type", 'm', ZyppFlags::RequiredArgument | ZyppFlags::Repeatable, ZyppFlags::StringVectorType( &_mediumTypes, "TYPE"),
+ _cmdContext == OptCommandCtx::ServiceContext ? _("Apply changes to services of specified type.") : _("Apply changes to repositories of specified type.")
+ }
+ }}};
+}
+
+void RepoServiceCommonSelectOptions::reset()
+{
+ _all = false;
+ _local = false;
+ _remote = false;
+ _mediumTypes.clear();
+}
+
+void RepoServiceCommonSelectOptions::fillFromCopts(Zypper &zypper)
+{
+ reset();
+ _all = copts.count("all");
+ _local = copts.count("local");
+ _remote = copts.count("remote");
+ _mediumTypes.insert( _mediumTypes.begin(), copts["medium-type"].begin(), copts["medium-type"].end());
+}
+
+
+std::vector<ZyppFlags::CommandGroup> RepoProperties::options()
+{
+ return {{{
+ { "priority", 'p', ZyppFlags::RequiredArgument, PriorityType( _priority, _priority ), _("Set priority of the repository.") },
+ { "keep-packages", 'k', ZyppFlags::NoArgument, ZyppFlags::TriBoolType( _keepPackages, ZyppFlags::StoreTrue, TriBool( true ) ), _("Enable RPM files caching.") },
+ { "no-keep-packages", 'K', ZyppFlags::NoArgument, ZyppFlags::TriBoolType( _keepPackages, ZyppFlags::StoreFalse, TriBool( false ) ), _("Disable RPM files caching.") },
+ { "gpgcheck", 'g', ZyppFlags::NoArgument, GPGCheckType( _gpgCheck, RepoInfo::GpgCheck::On ), _("Enable GPG check for this repository.") },
+ { "gpgcheck-strict", '\0', ZyppFlags::NoArgument, GPGCheckType( _gpgCheck, RepoInfo::GpgCheck::Strict ), _("Enable strict GPG check for this repository.") },
+ { "gpgcheck-allow-unsigned", '\0', ZyppFlags::NoArgument, GPGCheckType( _gpgCheck, RepoInfo::GpgCheck::AllowUnsigned ), str::Format(_("Short hand for '%1%'.") ) % "--gpgcheck-allow-unsigned-repo --gpgcheck-allow-unsigned-package" },
+ { "gpgcheck-allow-unsigned-repo", '\0', ZyppFlags::NoArgument, GPGCheckType( _gpgCheck, RepoInfo::GpgCheck::AllowUnsignedRepo ), _("Enable GPG check but allow the repository metadata to be unsigned.") },
+ { "gpgcheck-allow-unsigned-package", '\0', ZyppFlags::NoArgument, GPGCheckType( _gpgCheck, RepoInfo::GpgCheck::AllowUnsignedPackage ), _("Enable GPG check but allow installing unsigned packages from this repository.") },
+ { "no-gpgcheck", 'G', ZyppFlags::NoArgument, GPGCheckType( _gpgCheck, RepoInfo::GpgCheck::Off ), _("Disable GPG check for this repository.") },
+ { "default-gpgcheck", '\0', ZyppFlags::NoArgument, GPGCheckType( _gpgCheck, RepoInfo::GpgCheck::Default ), _("Use the global GPG check setting defined in /etc/zypp/zypp.conf. This is the default.") }
+ },{
+ //conflicting arguments
+ { "gpgcheck", "gpgcheck-strict", "gpgcheck-allow-unsigned", "gpgcheck-allow-unsigned-repo", "gpgcheck-allow-unsigned-package", "no-gpgcheck", "default-gpgcheck"}
+ }}};
+}
+
+void RepoProperties::reset()
+{
+ _priority = 0U;
+ _keepPackages = zypp::indeterminate;
+ _gpgCheck = zypp::RepoInfo::GpgCheck::indeterminate;
+}
+
+void RepoProperties::fillFromCopts(Zypper &zypper)
+{
+ reset();
+ _keepPackages = get_boolean_option( zypper, "keep-packages", "no-keep-packages" );
+ _gpgCheck = cli::gpgCheck( zypper );
+ _priority = priority_from_copts( zypper );
+}
+
+
+RSCommonListOptions::RSCommonListOptions(OptCommandCtx ctx)
+ : _cmdContext ( ctx )
+{ }
+
+RSCommonListOptions::RSCommonListOptions(OptCommandCtx ctx, ZypperBaseCommand &parent)
+ : BaseCommandOptionSet ( parent ),
+ _cmdContext ( ctx )
+{ }
+
+std::vector<ZyppFlags::CommandGroup> RSCommonListOptions::options()
+{
+
+ std::vector<ZyppFlags::CommandGroup> opts;
+
+ RSCommonListFlags showAllFlag = ListServiceShowAll;
+
+ if ( _cmdContext == OptCommandCtx::RepoContext ) {
+
+ opts.push_back ( {{
+ { "alias", 'a', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, ShowAlias ),
+ // translators: -a, --alias
+ _("Show also repository alias.")},
+ { "name", 'n', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, ShowName ),
+ // translators: -n, --name
+ _("Show also repository name.")},
+ { "refresh", 'r', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, ShowRefresh ),
+ // translators: -r, --refresh
+ _("Show also the autorefresh flag.")}
+ }} );
+
+ showAllFlag = ListRepoShowAll;
+ }
+
+ opts.push_back(
+ {{
+ { "uri", 'u', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, ShowURI ),
+ // translators: -u, --uri
+ _("Show also base URI of repositories.")},
+ { "url", '\0', ZyppFlags::NoArgument | ZyppFlags::Hidden, ZyppFlags::BitFieldType( _flags, ShowURI ), "" },
+ { "priority", 'p', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, ShowPriority ),
+ // translators: -p, --priority
+ _("Show also repository priority.") },
+ { "details", 'd', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, showAllFlag ),
+ // translators: -d, --details
+ _("Show more information like URI, priority, type.") }
+ }}
+ );
+
+ if ( _cmdContext == OptCommandCtx::ServiceContext ) {
+ //@NOTE attention -r clashes with --refresh in case of merging the options
+ opts.back().options.push_back(
+ { "with-repos", 'r', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, ShowWithRepos), _("Show also repositories belonging to the services.") }
+ );
+ } else {
+ opts.back().options.push_back(
+ { "service", 's', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, ShowWithService),
+ // translators: -s, --service
+ _("Show also alias of parent service.") }
+ );
+ }
+
+ opts.push_back({{
+ { "show-enabled-only", 'E', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, ShowEnabledOnly ),
+ // translators: -E, --show-enabled-only
+ _("Show enabled repos only.") },
+ { "sort-by-uri", 'U', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, RSCommonListFlags( ShowURI ) | SortByURI ),
+ // translators: -U, --sort-by-uri
+ _("Sort the list by URI.") },
+ { "sort-by-name", 'N', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, SortByName ),
+ // translators: -N, --sort-by-name
+ _("Sort the list by name.") },
+ { "sort-by-priority", 'P', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, RSCommonListFlags( ShowPriority ) | SortByPrio ),
+ // translators: -P, --sort-by-priority
+ _("Sort the list by repository priority.") }
+ }});
+
+ if ( _cmdContext == OptCommandCtx::RepoContext ) {
+ opts.back().options.push_back(
+ { "sort-by-alias", 'A', ZyppFlags::NoArgument, ZyppFlags::BitFieldType( _flags, RSCommonListFlags( ShowAlias ) | SortByAlias ),
+ // translators: -A, --sort-by-alias
+ _("Show also alias of parent service.") }
+ );
+ }
+
+ return opts;
+}
+
+void RSCommonListOptions::reset()
+{
+ _flags.unsetFlag( _flags.all() );
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_REPO_SERVICE_OPTIONSET_H_INCLUDED
+#define ZYPPER_COMMANDS_REPO_SERVICE_OPTIONSET_H_INCLUDED
+
+#include "basecommand.h"
+
+#include <zypp/TriBool.h>
+#include <zypp/RepoInfo.h>
+#include <zypp/base/Flags.h>
+
+enum class OptCommandCtx
+{
+ ServiceContext,
+ RepoContext
+};
+
+// Common Repo/Service properties (argdef only)
+// LEGACY: --refresh short option was -f in ADD_REPO, -r in all other Repo/Service commands.
+// Unfortunately -r is already --repo in ADD_REPO, so switching all Repo/Service commands
+// to prefer -f/F.
+class RepoServiceCommonOptions : public BaseCommandOptionSet
+{
+public:
+ RepoServiceCommonOptions( OptCommandCtx ctx );
+ RepoServiceCommonOptions( OptCommandCtx ctx, ZypperBaseCommand &parent );
+
+ // BaseCommandOptionSet interface
+ std::vector<zypp::ZyppFlags::CommandGroup> options() override;
+ void reset() override;
+
+ //will be removed
+ void fillFromCopts (Zypper &zypper );
+
+ std::string _name;
+ zypp::TriBool _enable = zypp::indeterminate;
+ zypp::TriBool _enableAutoRefresh = zypp::indeterminate;
+
+private:
+ OptCommandCtx _cmdContext = OptCommandCtx::RepoContext;
+};
+
+// Common modify Repo/Service aggregate options (argdef only)
+class RepoServiceCommonSelectOptions : public BaseCommandOptionSet
+{
+public:
+ RepoServiceCommonSelectOptions( OptCommandCtx ctx );
+ RepoServiceCommonSelectOptions( OptCommandCtx ctx, ZypperBaseCommand &parent );
+
+ // BaseCommandOptionSet interface
+ std::vector<zypp::ZyppFlags::CommandGroup> options() override;
+ void reset() override;
+
+ //will be removed
+ void fillFromCopts (Zypper &zypper );
+
+ bool _all = false;
+ bool _local = false;
+ bool _remote = false;
+ std::vector<std::string> _mediumTypes;
+
+private:
+ OptCommandCtx _cmdContext = OptCommandCtx::RepoContext;
+};
+
+class RepoProperties : public BaseCommandOptionSet
+{
+public:
+ using BaseCommandOptionSet::BaseCommandOptionSet;
+
+ // BaseCommandOptionSet interface
+ std::vector<zypp::ZyppFlags::CommandGroup> options() override;
+ void reset() override;
+
+ //will be removed
+ void fillFromCopts (Zypper &zypper );
+
+ unsigned _priority = 0U;
+ zypp::TriBool _keepPackages = zypp::indeterminate;
+ zypp::RepoInfo::GpgCheck _gpgCheck = zypp::RepoInfo::GpgCheck::indeterminate;
+};
+
+class RSCommonListOptions : public BaseCommandOptionSet
+{
+public:
+
+ RSCommonListOptions( OptCommandCtx ctx );
+ RSCommonListOptions( OptCommandCtx ctx, ZypperBaseCommand &parent );
+
+
+ enum RSCommonListFlagsBits
+ {
+ ShowAlias = 1, //< only supported in list repos
+ ShowName = 1 << 1, //< only supported in list repos
+ ShowRefresh = 1 << 2, //< only supported in list repos
+ ShowURI = 1 << 3, //< supported in service and repos
+ ShowPriority = 1 << 4, //< supported in service and repos
+ ShowWithRepos = 1 << 5, //< only supported in list services
+ ShowWithService = 1 << 6, //< only supported in list repos
+ ListServiceShowAll = ShowURI | ShowPriority | ShowWithRepos,
+ ListRepoShowAll = ShowAlias | ShowName | ShowRefresh | ShowURI | ShowPriority | ShowWithService,
+ ShowEnabledOnly = 1 << 7, //< supported in service and repos
+ SortByURI = 1 << 8, //< supported in service and repos
+ SortByAlias = 1 << 9, //< only supported in list repos
+ SortByName = 1 << 10, //< supported in service and repos
+ SortByPrio = 1 << 11, //< supported in service and repos
+ ServiceRepo = 1 << 15 //< special value used in list services
+ };
+ ZYPP_DECLARE_FLAGS( RSCommonListFlags, RSCommonListFlagsBits );
+
+ // BaseCommandOptionSet interface
+ std::vector<zypp::ZyppFlags::CommandGroup> options() override;
+ void reset() override;
+
+ RSCommonListFlags _flags;
+
+private:
+ OptCommandCtx _cmdContext = OptCommandCtx::RepoContext;
+};
+
+ZYPP_DECLARE_OPERATORS_FOR_FLAGS( RSCommonListOptions::RSCommonListFlags )
+
+
+#endif
--- /dev/null
+#ifndef ZYPPER_COMMANDS_SERVICES_H_INCLUDED
+#define ZYPPER_COMMANDS_SERVICES_H_INCLUDED
+
+#include "services/list.h"
+#include "services/refresh.h"
+#include "services/add.h"
+#include "services/modify.h"
+#include "services/remove.h"
+
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "add.h"
+#include "main.h"
+#include "repos.h"
+#include "Zypper.h"
+#include "commands/conditions.h"
+#include "utils/messages.h"
+#include "utils/misc.h"
+#include "utils/flags/flagtypes.h"
+
+#include <zypp/repo/RepoException.h>
+#include <zypp/Url.h>
+
+using namespace zypp;
+
+namespace {
+ZyppFlags::Value CheckIsServiceTypeVal( bool &target )
+{
+ return ZyppFlags::Value (
+ []() -> boost::optional<std::string>{
+ return boost::optional<std::string>();
+ },
+
+ [ &target ]( const ZyppFlags::CommandOption &opt, const boost::optional<std::string> &in ) {
+ if (!in)
+ ZYPP_THROW(ZyppFlags::MissingArgumentException(opt.name));
+
+ target = false;
+ try {
+ repo::ServiceType t ( *in );
+ target = true;
+ } catch ( const repo::RepoUnknownTypeException & e )
+ { }
+ }
+ );
+}
+
+void add_service( Zypper & zypper, const ServiceInfo & service )
+{
+ RepoManager manager( zypper.globalOpts().rm_options );
+
+ try
+ {
+ manager.addService( service );
+ }
+ catch ( const repo::RepoAlreadyExistsException & e )
+ {
+ ZYPP_CAUGHT( e );
+ ERR << "Service aliased '" << service.alias() << "' already exists." << endl;
+ zypper.out().error( str::Format(_("Service aliased '%s' already exists. Please use another alias.")) % service.alias() );
+ zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
+ return;
+ }
+ catch ( const Exception & e )
+ {
+ ZYPP_CAUGHT( e );
+ zypper.out().error( str::Format(_("Error occurred while adding service '%s'.")) % service.alias() );
+ zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
+ return;
+ }
+
+ MIL << "Service '" << service.alias() << "' has been added." << endl;
+ zypper.out().info( str::Format(_("Service '%s' has been successfully added.")) % service.asUserString() );
+}
+
+// ---------------------------------------------------------------------------
+
+void add_service_by_url( Zypper & zypper,
+ const Url & url,
+ const std::string & alias,
+ const RepoServiceCommonOptions &props )
+{
+ MIL << "going to add service by url (alias=" << alias << ", url=" << url << ")" << endl;
+
+ ServiceInfo service;
+
+ service.setAlias( alias.empty() ? timestamp() : alias );
+ parsed_opts::const_iterator it = zypper.cOpts().find("name");
+ if ( !props._name.empty() )
+ service.setName( props._name );
+ service.setUrl( url );
+
+ std::cout << "Setting new service " << alias << asString(props._enable) << " " << asString(props._enableAutoRefresh) << endl;
+
+ service.setEnabled( indeterminate( props._enable ) ? true : bool(props._enable) );
+ service.setAutorefresh( indeterminate( props._enableAutoRefresh ) ? true : bool(props._enableAutoRefresh) );
+
+ add_service( zypper, service );
+}
+
+
+}
+
+AddServiceCmd::AddServiceCmd( const std::vector<std::string> &commandAliases_r ) :
+ ZypperBaseCommand(
+ commandAliases_r,
+ // translators: command synopsis; do not translate lowercase words
+ _("addservice (as) [OPTIONS] <URI> <ALIAS>"),
+ _("Add a new service."),
+ _("Add a repository index service to the system."),
+ ResetRepoManager
+ )
+{
+
+}
+
+zypp::ZyppFlags::CommandGroup AddServiceCmd::cmdOptions() const
+{
+ return {{
+ { "type",
+ 't',
+ ZyppFlags::RequiredArgument | ZyppFlags::Deprecated,
+ ZyppFlags::WarnOptionVal( Zypper::instance().out(), legacyCLIStr( "type", "", LegacyCLIMsgType::Ignored ), Out::NORMAL, CheckIsServiceTypeVal(const_cast<bool&>(_isService))),
+ _("The type of service is always autodetected. This option is ignored.")
+ }
+ }};
+}
+
+void AddServiceCmd::doReset()
+{
+ _isService = true;
+}
+
+int AddServiceCmd::execute( Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r )
+{
+ // too many arguments
+ if ( positionalArgs_r.size() > 2 )
+ {
+ report_too_many_arguments( help() );
+ return ( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+
+ // missing arguments
+ if ( positionalArgs_r.size() < 2 )
+ {
+ report_required_arg_missing( zypp_r.out(), help() );
+ return ( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+
+ Url url = make_url( positionalArgs_r[0] );
+ if ( !url.isValid() ) {
+ return( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ }
+
+ if ( _isService )
+ add_service_by_url( zypp_r, url, positionalArgs_r[1], _commonProps );
+ else {
+ //legacy behaviour
+ add_repo_by_url( zypp_r, url, positionalArgs_r[1], _commonProps, RepoProperties(), false);
+ }
+
+ return zypp_r.exitCode();
+}
+
+
+std::vector<BaseCommandConditionPtr> AddServiceCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_SERVICES_ADD_H_INCLUDED
+#define ZYPPER_COMMANDS_SERVICES_ADD_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "commands/reposerviceoptionsets.h"
+#include "utils/flags/zyppflags.h"
+
+#include <zypp/base/Flags.h>
+#include <zypp/repo/ServiceType.h>
+
+class AddServiceCmd : public ZypperBaseCommand
+{
+public:
+ AddServiceCmd( const std::vector<std::string> &commandAliases_r );
+
+ // ZypperBaseCommand interface
+protected:
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute( Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r ) override;
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+
+private:
+ bool _isService = true;
+ RepoServiceCommonOptions _commonProps{ OptCommandCtx::ServiceContext, *this};
+};
+
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+
+#include "common.h"
+#include "repos.h"
+
+#include <zypp/media/MediaException.h>
+
+ServiceList get_all_services( Zypper & zypper )
+{
+ RepoManager & manager( zypper.repoManager() );
+ ServiceList services;
+
+ try
+ {
+ // RIS type services
+ for_( it, manager.serviceBegin(), manager.serviceEnd() )
+ {
+ services.insert( services.end(), ServiceInfo_Ptr( new ServiceInfo( *it ) ) ); // copy needed?
+ }
+
+ // non-services repos
+ for_( it, manager.repoBegin(), manager.repoEnd() )
+ {
+ if ( !it->service().empty() )
+ continue;
+ services.insert( services.end(), RepoInfo_Ptr( new RepoInfo( *it ) ) ); // copy needed?
+ }
+ }
+ catch ( const Exception &e )
+ {
+ ZYPP_CAUGHT(e);
+ zypper.out().error( e, _("Error reading services:") );
+ exit( ZYPPER_EXIT_ERR_ZYPP );
+ }
+
+ return services;
+}
+
+bool match_service( Zypper & zypper, std::string str, repo::RepoInfoBase_Ptr & service_ptr, bool looseAuth, bool looseQuery )
+{
+ ServiceList known = get_all_services( zypper );
+ bool found = false;
+
+ unsigned number = 0; // service number start with 1
+ for_( known_it, known.begin(), known.end() )
+ {
+ ++number;
+ unsigned tmp = 0;
+ safe_lexical_cast( str, tmp ); // try to make an int out of the string
+
+ try
+ {
+ // match by alias or number
+ found = (*known_it)->alias() == str || tmp == number;
+
+ // match by URL
+ if ( !found )
+ {
+ url::ViewOption urlview = url::ViewOption::DEFAULTS + url::ViewOption::WITH_PASSWORD;
+ if ( looseAuth )//zypper.cOpts().count("loose-auth") )
+ {
+ urlview = urlview - url::ViewOptions::WITH_PASSWORD - url::ViewOptions::WITH_USERNAME;
+ }
+ if ( looseQuery ) //zypper.cOpts().count("loose-query") )
+ urlview = urlview - url::ViewOptions::WITH_QUERY_STR;
+
+ ServiceInfo_Ptr s_ptr = dynamic_pointer_cast<ServiceInfo>(*known_it);
+
+ if ( !( urlview.has(url::ViewOptions::WITH_PASSWORD) && urlview.has(url::ViewOptions::WITH_QUERY_STR) ) )
+ {
+ if ( s_ptr )
+ found = Url(str).asString(urlview) == s_ptr->url().asString(urlview);
+ else
+ {
+ RepoInfo_Ptr r_ptr = dynamic_pointer_cast<RepoInfo>(*known_it);
+ if ( !r_ptr->baseUrlsEmpty() )
+ {
+ for_( urlit, r_ptr->baseUrlsBegin(), r_ptr->baseUrlsEnd() )
+ if ( urlit->asString(urlview) == Url(str).asString(urlview) )
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( s_ptr )
+ found = ( Url(str) == s_ptr->url() );
+ else
+ {
+ RepoInfo_Ptr r_ptr = dynamic_pointer_cast<RepoInfo>(*known_it);
+ if ( !r_ptr->baseUrlsEmpty() )
+ {
+ found = find( r_ptr->baseUrlsBegin(), r_ptr->baseUrlsEnd(), Url(str) ) != r_ptr->baseUrlsEnd();
+ }
+ }
+ }
+ }
+ if ( found )
+ {
+ service_ptr = *known_it;
+ break;
+ }
+ }
+ catch( const url::UrlException & )
+ {}
+
+ } // END for all known services
+
+ return found;
+}
+
+bool refresh_service(Zypper & zypper, const ServiceInfo & service, RepoManager::RefreshServiceFlags flags_r)
+{
+ MIL << "going to refresh service '" << service.alias() << "'" << endl;
+ init_target( zypper ); // need targetDistribution for service refresh
+ RepoManager & manager( zypper.repoManager() );
+
+ bool error = true;
+ try
+ {
+ zypper.out().info( str::form(_("Refreshing service '%s'."), service.asUserString().c_str() ) );
+ manager.refreshService( service, flags_r );
+ error = false;
+ }
+ catch ( const repo::ServicePluginInformalException & e )
+ {
+ ZYPP_CAUGHT( e );
+ zypper.out().error( e, str::form(_("Problem retrieving the repository index file for service '%s':"),
+ service.asUserString().c_str()));
+ zypper.out().warning( str::form( _("Skipping service '%s' because of the above error."),
+ service.asUserString().c_str()));
+ // this is just an informal note. The service will be used as is (usually empty)
+ error = false;
+ }
+ catch ( const media::MediaException & e )
+ {
+ ZYPP_CAUGHT( e );
+ zypper.out().error( e, str::form(_("Problem retrieving the repository index file for service '%s':"),
+ service.asUserString().c_str() ),
+ _("Check if the URI is valid and accessible.") );
+ zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
+ }
+
+ return error;
+}
+
+void remove_service( Zypper & zypper, const ServiceInfo & service )
+{
+ RepoManager & manager( zypper.repoManager() );
+
+ zypper.out().info( str::Format(_("Removing service '%s':")) % service.asUserString() );
+ manager.removeService( service );
+ MIL << "Service '" << service.alias() << "' has been removed." << endl;
+ zypper.out().info( str::Format(_("Service '%s' has been removed.")) % service.asUserString() );
+}
+
+
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_SERVICES_COMMON_H_INCLUDED
+#define ZYPPER_COMMANDS_SERVICES_COMMON_H_INCLUDED
+
+#include "Zypper.h"
+
+#include <zypp/RepoInfo.h>
+#include <zypp/repo/RepoInfoBase.h>
+#include <zypp/RepoManager.h>
+
+#include <list>
+
+struct RepoCollector
+{
+ bool collect( const zypp::RepoInfo & repo )
+ {
+ repos.push_back( repo );
+ return true;
+ }
+ RepoInfoList repos;
+};
+
+typedef std::list<zypp::repo::RepoInfoBase_Ptr> ServiceList;
+
+ServiceList get_all_services( Zypper & zypper );
+
+bool match_service( Zypper & zypper, std::string str, repo::RepoInfoBase_Ptr & service_ptr, bool looseAuth, bool looseQuery );
+bool refresh_service(Zypper & zypper, const ServiceInfo & service, RepoManager::RefreshServiceFlags flags_r = RepoManager::RefreshServiceFlags() );
+void remove_service( Zypper & zypper, const ServiceInfo & service );
+
+
+#endif
--- /dev/null
+#include "list.h"
+#include "main.h"
+#include "repos.h"
+#include "common.h"
+
+#include "utils/flags/flagtypes.h"
+
+using namespace zypp;
+
+namespace {
+
+void service_list_tr( Zypper & zypper,
+ Table & tbl,
+ const repo::RepoInfoBase_Ptr & srv,
+ unsigned reponumber,
+ const RSCommonListOptions::RSCommonListFlags & flags )
+{
+ ServiceInfo_Ptr service = dynamic_pointer_cast<ServiceInfo>(srv);
+ RepoInfo_Ptr repo;
+ if ( ! service )
+ repo = dynamic_pointer_cast<RepoInfo>(srv);
+
+ RepoGpgCheckStrings repoGpgCheck( service ? RepoGpgCheckStrings(*service) : RepoGpgCheckStrings(*repo) );
+
+ TableRow tr( 8 );
+
+ // number
+ if ( flags & RSCommonListOptions::ServiceRepo )
+ {
+ if ( repo && ! repo->enabled() )
+ tr << ColorString( repoGpgCheck._tagColor, "-" ).str();
+ else
+ tr << "";
+ }
+ else
+ tr << ColorString( repoGpgCheck._tagColor, str::numstring(reponumber) ).str();
+
+ // alias
+ tr << srv->alias();
+ // name
+ tr << srv->name();
+ // enabled?
+ tr << repoGpgCheck._enabledYN.str();
+ // GPG Check
+ tr << repoGpgCheck._gpgCheckYN.str();
+ // autorefresh?
+ tr << repoAutorefreshStr( *srv );
+
+ // priority
+ if ( flags & RSCommonListOptions::ShowPriority )
+ {
+ if ( service )
+ tr << "";
+ else
+ tr << repoPriorityNumber( repo->priority(), 4 );
+ }
+
+ // type
+ if ( service )
+ tr << service->type().asString();
+ else
+ tr << repo->type().asString();
+
+ // url
+ if ( flags & RSCommonListOptions::ShowURI )
+ {
+ if ( service )
+ tr << service->url().asString();
+ else
+ tr << repo->url().asString();
+ }
+
+ tbl << tr;
+}
+
+}
+
+ListServicesCmd::ListServicesCmd(const std::vector<std::string> &commandAliases_r)
+ : ZypperBaseCommand (
+ commandAliases_r,
+ _("services (ls) [OPTIONS]"),
+ _("List all defined services."),
+ _("List defined services."),
+ ResetRepoManager
+ )
+{
+
+}
+
+void ListServicesCmd::printServiceList( Zypper &zypp_r )
+{
+ ServiceList services = get_all_services( zypp_r );
+
+ Table tbl;
+
+ bool with_repos = _listOptions._flags.testFlag( RSCommonListOptions::ShowWithRepos );
+ //! \todo string type = zypper.cOpts().count("type");
+
+ // header
+ {
+ TableHeader th;
+ // fixed 'zypper services' columns
+ th << "#"
+ << _("Alias")
+ << _("Name")
+ << _("Enabled")
+ << _("GPG Check")
+ // translators: 'zypper repos' column - whether autorefresh is enabled for the repository
+ << _("Refresh");
+ // optional columns
+ if ( _listOptions._flags.testFlag( RSCommonListOptions::ShowPriority ) )
+ // translators: repository priority (in zypper repos -p or -d)
+ th << _("Priority");
+ th << _("Type");
+ if ( _listOptions._flags.testFlag( RSCommonListOptions::ShowURI ) )
+ th << _("URI");
+ tbl << std::move(th);
+ }
+
+ bool show_enabled_only = _listOptions._flags.testFlag( RSCommonListOptions::ShowEnabledOnly );
+
+ int i = 0;
+ for_( it, services.begin(), services.end() )
+ {
+ ++i; // continuous numbering including skipped ones
+
+ bool servicePrinted = false;
+ // Unconditionally print the service before the 1st repo is
+ // printed. Undesired, but possible, that a disabled service
+ // owns (manually) enabled repos.
+ if ( with_repos && dynamic_pointer_cast<ServiceInfo>(*it) )
+ {
+ RepoCollector collector;
+ RepoManager & rm( zypp_r.repoManager() );
+
+ rm.getRepositoriesInService( (*it)->alias(),
+ make_function_output_iterator( bind( &RepoCollector::collect, &collector, _1 ) ) );
+
+ for_( repoit, collector.repos.begin(), collector.repos.end() )
+ {
+ repo::RepoInfoBase_Ptr ptr( new RepoInfo(*repoit) ); // copy needed?
+
+ if ( show_enabled_only && !repoit->enabled() )
+ continue;
+
+ if ( !servicePrinted )
+ {
+ service_list_tr( zypp_r, tbl, *it, i, _listOptions._flags );
+ servicePrinted = true;
+ }
+ // ServiceRepo: we print repos of the current service
+ service_list_tr( zypp_r, tbl, ptr, i, _listOptions._flags | RSCommonListOptions::ServiceRepo );
+ }
+ }
+ if ( servicePrinted )
+ continue;
+
+ // Here: No repo enforced printing the service, so do so if
+ // necessary.
+ if ( show_enabled_only && !(*it)->enabled() )
+ continue;
+
+ service_list_tr( zypp_r, tbl, *it, i, _listOptions._flags );
+ }
+
+ if ( tbl.empty() )
+ zypp_r.out().info( str::form(_("No services defined. Use the '%s' command to add one or more services."),
+ "zypper addservice" ) );
+ else
+ {
+ // sort
+ if ( _listOptions._flags.testFlag( RSCommonListOptions::SortByURI ) )
+ {
+ if ( _listOptions._flags.testFlag( RSCommonListOptions::ListServiceShowAll ) )
+ tbl.sort( 7 );
+ else if ( _listOptions._flags.testFlag( RSCommonListOptions::ShowPriority ) )
+ tbl.sort( 7 );
+ else
+ tbl.sort( 6 );
+ }
+#if 0
+ //BUG? This option did not exist
+ else if ( zypper.cOpts().count("sort-by-alias") )
+ tbl.sort( 1 );
+#endif
+ else if ( _listOptions._flags.testFlag( RSCommonListOptions::SortByName ) )
+ tbl.sort( 2 );
+ else if ( _listOptions._flags.testFlag( RSCommonListOptions::SortByPrio) )
+ tbl.sort( 5 );
+
+ // print
+ cout << tbl;
+ }
+}
+
+void ListServicesCmd::printXMLServiceList( Zypper &zypp_r )
+{
+ ServiceList services = get_all_services( zypp_r );
+
+ cout << "<service-list>" << endl;
+
+ ServiceInfo_Ptr s_ptr;
+ for_( it, services.begin(), services.end() )
+ {
+ s_ptr = dynamic_pointer_cast<ServiceInfo>(*it);
+ // print also service's repos
+ if ( s_ptr )
+ {
+ RepoCollector collector;
+ RepoManager & rm( zypp_r.repoManager() );
+ rm.getRepositoriesInService( (*it)->alias(),
+ make_function_output_iterator( bind( &RepoCollector::collect, &collector, _1 ) ) );
+ std::ostringstream sout;
+ for_( repoit, collector.repos.begin(), collector.repos.end() )
+ repoit->dumpAsXmlOn( sout );
+ (*it)->dumpAsXmlOn( cout, sout.str() );
+ continue;
+ }
+
+ (*it)->dumpAsXmlOn( cout );
+ }
+
+ cout << "</service-list>" << endl;
+}
+
+ZyppFlags::CommandGroup ListServicesCmd::cmdOptions() const
+{
+ return ZyppFlags::CommandGroup();
+}
+
+void ListServicesCmd::doReset()
+{
+}
+
+int ListServicesCmd::execute( Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r )
+{
+ if ( _listOptions._flags.testFlag( RSCommonListOptions::ShowWithRepos) )
+ checkIfToRefreshPluginServices( zypp_r );
+
+ if ( zypp_r.out().type() == Out::TYPE_XML ) {
+ printXMLServiceList( zypp_r );
+ return ZYPPER_EXIT_OK;
+ }
+
+ printServiceList( zypp_r );
+ return ZYPPER_EXIT_OK;
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_SERVICES_LIST_H_INCLUDED
+#define ZYPPER_COMMANDS_SERVICES_LIST_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "commands/reposerviceoptionsets.h"
+#include "utils/flags/zyppflags.h"
+
+#include <zypp/base/Flags.h>
+
+class ListServicesCmd : public ZypperBaseCommand
+{
+public:
+ ListServicesCmd ( const std::vector<std::string> &commandAliases_r );
+
+private:
+ void printServiceList ( Zypper &zypp_r );
+ void printXMLServiceList ( Zypper &zypp_r );
+
+ // ZypperBaseCommand interface
+protected:
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r) override;
+
+private:
+ RSCommonListOptions _listOptions { OptCommandCtx::ServiceContext, *this };
+};
+
+
+#endif
--- /dev/null
+#include "modify.h"
+#include "Zypper.h"
+#include "utils/flags/flagtypes.h"
+#include "utils/messages.h"
+
+#include "commands/commandhelpformatter.h"
+#include "commands/conditions.h"
+#include "commands/services/common.h"
+
+#include "repos.h"
+
+
+ModifyServiceCmd::ModifyServiceCmd( const std::vector<std::string> &commandAliases_r )
+ : ZypperBaseCommand(
+ commandAliases_r,
+ {
+ // translators: command synopsis; do not translate lowercase words
+ _("modifyservice (ms) <OPTIONS> <ALIAS|#|URI>"),
+ // translators: command synopsis; do not translate lowercase words
+ str::Format( _("modifyservice (ms) <OPTIONS> <%1%>") ) % "--all|--remote|--local|--medium-type"
+ },
+ _("Modify specified service."),
+ str::Format(_("Modify properties of services specified by alias, number, or URI, or by the '%1%' aggregate options.") ) % "--all, --remote, --local, --medium-type",
+ ResetRepoManager
+ )
+{
+
+}
+
+std::vector<BaseCommandConditionPtr> ModifyServiceCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
+
+zypp::ZyppFlags::CommandGroup ModifyServiceCmd::cmdOptions() const
+{
+ auto that = const_cast<ModifyServiceCmd *>(this);
+ return {
+ _("Advanced:"),
+ {
+ { "ar-to-enable", 'i', ZyppFlags::RequiredArgument | ZyppFlags::Repeatable, ZyppFlags::StringVectorType( &that->_arToEnable, "ALIAS"), _("Add a RIS service repository to enable.")},
+ { "ar-to-disable", 'I', ZyppFlags::RequiredArgument | ZyppFlags::Repeatable, ZyppFlags::StringVectorType( &that->_arToDisable, "ALIAS"), _("Add a RIS service repository to disable.")},
+ { "rr-to-enable", 'j', ZyppFlags::RequiredArgument | ZyppFlags::Repeatable, ZyppFlags::StringVectorType( &that->_rrToEnable, "ALIAS"), _("Remove a RIS service repository to enable.")},
+ { "rr-to-disable", 'J', ZyppFlags::RequiredArgument | ZyppFlags::Repeatable, ZyppFlags::StringVectorType( &that->_rrToDisable, "ALIAS"), _("Remove a RIS service repository to disable.")},
+ { "cl-to-enable", 'k', ZyppFlags::NoArgument, ZyppFlags::BoolType( &that->_clearToEnable, ZyppFlags::StoreTrue), _("Clear the list of RIS repositories to enable.")},
+ { "cl-to-disable", 'K', ZyppFlags::NoArgument, ZyppFlags::BoolType( &that->_clearToDisable, ZyppFlags::StoreTrue), _("Clear the list of RIS repositories to disable.")},
+ //some legacy options
+ {"legacy-refresh", 'r', ZyppFlags::NoArgument | ZyppFlags::Hidden, ZyppFlags::TriBoolType( that->_commonProperties._enableAutoRefresh, ZyppFlags::StoreTrue ), "" },
+ {"legacy-no-refresh", 'R', ZyppFlags::NoArgument | ZyppFlags::Hidden, ZyppFlags::TriBoolType( that->_commonProperties._enableAutoRefresh, ZyppFlags::StoreFalse), "" }
+ }};
+}
+
+void ModifyServiceCmd::doReset()
+{
+ _arToEnable.clear();
+ _arToDisable.clear();
+ _rrToEnable.clear();
+ _rrToDisable.clear();
+ _clearToEnable = false;
+ _clearToDisable = false;
+}
+
+int ModifyServiceCmd::execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r)
+{
+ bool non_alias = _selectOptions._all || _selectOptions._local || _selectOptions._remote || (!_selectOptions._mediumTypes.empty());
+
+ if ( positionalArgs_r.size() < 1 && !non_alias )
+ {
+ // translators: aggregate option is e.g. "--all". This message will be
+ // followed by ms command help text which will explain it
+ zypp_r.out().error(_("Alias or an aggregate option is required."));
+ ERR << "No alias argument given." << endl;
+ zypp_r.out().info( help() );
+ return ZYPPER_EXIT_ERR_INVALID_ARGS;
+ }
+ // too many arguments
+ if ( positionalArgs_r.size() > 1 || ( positionalArgs_r.size() > 0 && non_alias ) )
+ {
+ report_too_many_arguments( help() );
+ return ZYPPER_EXIT_ERR_INVALID_ARGS;
+ }
+
+ if ( non_alias )
+ {
+ modifyServicesByOption( zypp_r );
+ }
+ else
+ {
+ repo::RepoInfoBase_Ptr srv;
+ if ( match_service( zypp_r, positionalArgs_r[0], srv, false, false ) )
+ {
+ if ( dynamic_pointer_cast<ServiceInfo>(srv) )
+ modifyService( zypp_r, srv->alias() );
+ else {
+ RepoProperties rProps;
+ rProps.reset();
+ modify_repo( zypp_r, srv->alias(), _commonProperties, rProps );
+ }
+ }
+ else
+ {
+ zypp_r.out().error( str::Format(_("Service '%s' not found.")) % positionalArgs_r[0] );
+ ERR << "Service " << positionalArgs_r[0] << " not found" << endl;
+ }
+ }
+ return zypp_r.exitCode();
+}
+
+
+std::string ModifyServiceCmd::help()
+{
+ CommandHelpFormater formatter;
+
+ formatter << ZypperBaseCommand::help();
+
+ formatter
+ .legacyOptionSection()
+ .legacyOption( "-r", "-f" )
+ .legacyOption( "-R", "-F" );
+
+ return formatter;
+}
+
+
+int ModifyServiceCmd::modifyService( Zypper & zypper, const std::string & alias )
+{
+ // enable/disable repo
+ const TriBool &enable = _commonProperties._enable;
+ DBG << "enable = " << enable << endl;
+
+ // autorefresh
+ const TriBool &autoref = _commonProperties._enableAutoRefresh;
+ DBG << "autoref = " << autoref << endl;
+
+ try
+ {
+ RepoManager & manager = zypper.repoManager();
+ ServiceInfo srv( manager.getService( alias ) );
+
+ bool changed_enabled = false;
+ bool changed_autoref = false;
+
+ if ( !indeterminate(enable) )
+ {
+ if ( enable != srv.enabled() )
+ changed_enabled = true;
+ srv.setEnabled( enable );
+ }
+
+ if ( !indeterminate(autoref) )
+ {
+ if ( autoref != srv.autorefresh() )
+ changed_autoref = true;
+ srv.setAutorefresh( autoref );
+ }
+
+ const std::string &name = _commonProperties._name;
+ if ( ! name.empty() )
+ srv.setName( name );
+
+ std::set<std::string> artoenable;
+ std::set<std::string> artodisable;
+ std::set<std::string> rrtoenable;
+ std::set<std::string> rrtodisable;
+
+ // RIS repos to enable
+ if ( _clearToEnable )
+ {
+ rrtoenable.insert( srv.reposToEnableBegin(), srv.reposToEnableEnd() );
+ srv.clearReposToEnable();
+ }
+ else
+ {
+ for_( rit, _arToEnable.begin(), _arToEnable.end() )
+ {
+ if ( !srv.repoToEnableFind( *rit ) )
+ {
+ srv.addRepoToEnable( *rit );
+ artoenable.insert( *rit );
+ }
+ }
+
+ for_( rit, _rrToEnable.begin(), _rrToEnable.end() )
+ {
+ if ( srv.repoToEnableFind( *rit ) )
+ {
+ srv.delRepoToEnable( *rit );
+ rrtoenable.insert( *rit );
+ }
+ }
+ }
+
+ // RIS repos to disable
+ if ( _clearToDisable )
+ {
+ rrtodisable.insert( srv.reposToDisableBegin(), srv.reposToDisableEnd() );
+ srv.clearReposToDisable();
+ }
+ else
+ {
+ for_( rit, _arToDisable.begin(), _arToDisable.end() )
+ {
+ if ( !srv.repoToDisableFind( *rit ) )
+ {
+ srv.addRepoToDisable( *rit );
+ artodisable.insert( *rit );
+ }
+ }
+
+ for_( rit, _rrToDisable.begin(), _rrToDisable.end() )
+ {
+ if (srv.repoToDisableFind( *rit ) )
+ {
+ srv.delRepoToDisable( *rit );
+ rrtodisable.insert( *rit );
+ }
+ }
+ }
+
+ if ( changed_enabled
+ || changed_autoref
+ || !name.empty()
+ || !artoenable.empty()
+ || !artodisable.empty()
+ || !rrtoenable.empty()
+ || !rrtodisable.empty() )
+ {
+ manager.modifyService( alias, srv );
+
+ if ( changed_enabled )
+ {
+ if ( srv.enabled() )
+ zypper.out().info( str::Format(_("Service '%s' has been successfully enabled.")) % alias );
+ else
+ zypper.out().info( str::Format(_("Service '%s' has been successfully disabled.")) % alias );
+ }
+
+ if ( changed_autoref )
+ {
+ if ( srv.autorefresh() )
+ zypper.out().info( str::Format(_("Autorefresh has been enabled for service '%s'.")) % alias );
+ else
+ zypper.out().info( str::Format(_("Autorefresh has been disabled for service '%s'.")) % alias );
+ }
+
+ if ( !name.empty() )
+ {
+ zypper.out().info( str::Format(_("Name of service '%s' has been set to '%s'.")) % alias % name );
+ }
+
+ if ( !artoenable.empty() )
+ {
+ zypper.out().info( str::Format(PL_("Repository '%s' has been added to enabled repositories of service '%s'",
+ "Repositories '%s' have been added to enabled repositories of service '%s'",
+ artoenable.size()))
+ % str::join( artoenable.begin(), artoenable.end(), ", " ) % alias );
+ }
+ if ( !artodisable.empty() )
+ {
+ zypper.out().info( str::Format(PL_("Repository '%s' has been added to disabled repositories of service '%s'",
+ "Repositories '%s' have been added to disabled repositories of service '%s'",
+ artodisable.size()))
+ % str::join( artodisable.begin(), artodisable.end(), ", " ) % alias );
+ }
+ if ( !rrtoenable.empty() )
+ {
+ zypper.out().info( str::Format(PL_("Repository '%s' has been removed from enabled repositories of service '%s'",
+ "Repositories '%s' have been removed from enabled repositories of service '%s'",
+ rrtoenable.size()))
+ % str::join( rrtoenable.begin(), rrtoenable.end(), ", " ) % alias );
+ }
+ if ( !rrtodisable.empty())
+ {
+ zypper.out().info( str::Format(PL_("Repository '%s' has been removed from disabled repositories of service '%s'",
+ "Repositories '%s' have been removed from disabled repositories of service '%s'",
+ rrtodisable.size()))
+ % str::join( rrtodisable.begin(), rrtodisable.end(), ", " ) % alias );
+ }
+ }
+ else
+ {
+ MIL << "Nothing to modify in '" << alias << "':" << srv << endl;
+ zypper.out().info( str::Format(_("Nothing to change for service '%s'.")) % alias );
+ }
+ }
+ catch ( const Exception & ex )
+ {
+ ERR << "Error while modifying the service:" << ex.asUserString() << endl;
+ zypper.out().error( ex, _("Error while modifying the service:"),
+ str::Format(_("Leaving service %s unchanged.")) % alias );
+ return ZYPPER_EXIT_ERR_ZYPP;
+ }
+
+ return ZYPPER_EXIT_OK;
+}
+
+// ---------------------------------------------------------------------------
+
+void ModifyServiceCmd::modifyServicesByOption( Zypper & zypper )
+{
+ ServiceList known = get_all_services( zypper );
+ std::set<std::string> repos_to_modify;
+ std::set<std::string> services_to_modify;
+
+ if ( _selectOptions._all )
+ {
+ for_( it, known.begin(), known.end() )
+ {
+ ServiceInfo_Ptr sptr = dynamic_pointer_cast<ServiceInfo>(*it);
+ if ( sptr )
+ modifyService( zypper, sptr->alias() );
+ else {
+ RepoProperties rProps;
+ rProps.reset();
+ modify_repo( zypper, (*it)->alias(), _commonProperties, rProps );
+ }
+ }
+ return;
+ }
+
+ bool local = _selectOptions._local;
+ bool remote = _selectOptions._remote;
+
+ std::set<std::string> schemes( _selectOptions._mediumTypes.begin(), _selectOptions._mediumTypes.end() );
+
+ for_( it, known.begin(), known.end() )
+ {
+ ServiceInfo_Ptr sptr = dynamic_pointer_cast<ServiceInfo>(*it);
+ Url url;
+ if ( sptr )
+ url = sptr->url();
+ else
+ {
+ RepoInfo_Ptr rptr = dynamic_pointer_cast<RepoInfo>(*it);
+ if ( !rptr->baseUrlsEmpty() )
+ url = rptr->url();
+ }
+
+ if ( url.isValid() )
+ {
+ bool modify = false;
+ if ( local && ! url.schemeIsDownloading() )
+ modify = true;
+
+ if ( !modify && remote && url.schemeIsDownloading() )
+ modify = true;
+
+ if ( !modify && schemes.find(url.getScheme()) != schemes.end() )
+ modify = true;
+
+ if ( modify )
+ {
+ std::string alias = (*it)->alias();
+ if ( sptr )
+ services_to_modify.insert( alias );
+ else
+ repos_to_modify.insert( alias );
+ }
+ }
+ else
+ WAR << "got invalid url: " << url.asString() << endl;
+ }
+
+ for_( it, services_to_modify.begin(), services_to_modify.end() )
+ modifyService( zypper, *it );
+
+ RepoProperties rProps;
+ rProps.reset();
+ for_( it, repos_to_modify.begin(), repos_to_modify.end() )
+ modify_repo( zypper, *it, _commonProperties, rProps );
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_SERVICES_MODIFY_H_INCLUDED
+#define ZYPPER_COMMANDS_SERVICES_MODIFY_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "commands/reposerviceoptionsets.h"
+#include "utils/flags/zyppflags.h"
+
+#include <zypp/base/Flags.h>
+
+class ModifyServiceCmd : public ZypperBaseCommand
+{
+public:
+ ModifyServiceCmd( const std::vector<std::string> &commandAliases_r );
+
+ // ZypperBaseCommand interface
+ std::string help() override;
+
+protected:
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp_r, const std::vector<std::string> &positionalArgs_r) override;
+
+private:
+ int modifyService( Zypper & zypper, const std::string & alias );
+ void modifyServicesByOption( Zypper & zypper );
+
+private:
+ std::vector<std::string> _arToEnable;
+ std::vector<std::string> _arToDisable;
+ std::vector<std::string> _rrToEnable;
+ std::vector<std::string> _rrToDisable;
+ bool _clearToEnable = false;
+ bool _clearToDisable = false;
+ RepoServiceCommonOptions _commonProperties { OptCommandCtx::ServiceContext, *this };
+ RepoServiceCommonSelectOptions _selectOptions { OptCommandCtx::ServiceContext, *this };
+};
+
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "refresh.h"
+#include "main.h"
+#include "Zypper.h"
+#include "repos.h"
+
+#include "common.h"
+#include "utils/flags/flagtypes.h"
+#include "commands/repos/refresh.h"
+#include "commands/conditions.h"
+
+#include <zypp/repo/RepoInfoBase.h>
+#include <zypp/base/Iterator.h>
+#include <zypp/media/MediaException.h>
+
+using namespace zypp;
+
+/**
+ * Try to find ServiceInfo or RepoInfo counterparts among known services by alias, number,
+ * or URI, based on the list of strings given as the iterator range \a begin and
+ * \a end. Matching objects will be added to \a services (as RepoInfoBase_Ptr) and those
+ * with no match will be added to \a not_found.
+ */
+template<typename T>
+void get_services( Zypper & zypper, const T & begin, const T & end,
+ ServiceList & services, std::list<std::string> & not_found )
+{
+ for_( it, begin, end )
+ {
+ repo::RepoInfoBase_Ptr service;
+
+ if ( !match_service( zypper, *it, service, false, false ) )
+ {
+ not_found.push_back( *it );
+ continue;
+ }
+
+ // service found
+ // is it a duplicate? compare by alias and URIs
+ //! \todo operator== in RepoInfo?
+ bool duplicate = false;
+ for_( serv_it, services.begin(), services.end() )
+ {
+ ServiceInfo_Ptr s_ptr = dynamic_pointer_cast<ServiceInfo>(*serv_it);
+ ServiceInfo_Ptr current_service_ptr = dynamic_pointer_cast<ServiceInfo>(service);
+
+ // one is a service, the other is a repo
+ if ( s_ptr && !current_service_ptr )
+ continue;
+
+ // service
+ if ( s_ptr )
+ {
+ if ( s_ptr->alias() == current_service_ptr->alias()
+ && s_ptr->url() == current_service_ptr->url() )
+ {
+ duplicate = true;
+ break;
+ }
+ }
+ // repo
+ else if ( repo_cmp_alias_urls( *dynamic_pointer_cast<RepoInfo>(service),
+ *dynamic_pointer_cast<RepoInfo>(*serv_it) ) )
+ {
+ duplicate = true;
+ break;
+ }
+ } // END for all found so far
+
+ if ( !duplicate )
+ services.push_back( service );
+ }
+}
+
+/**
+ * Say "Service %s not found" for all strings in \a not_found list.
+ */
+static void report_unknown_services( Out & out, std::list<std::string> not_found )
+{
+ for_( it, not_found.begin(), not_found.end() )
+ out.error( str::Format(_("Service '%s' not found by its alias, number, or URI.")) % *it );
+
+ if ( !not_found.empty() )
+ out.info( str::Format(_("Use '%s' to get the list of defined services.")) % "zypper repos" );
+}
+
+RefreshServicesCmd::RefreshServicesCmd( const std::vector<std::string> &commandAliases_r ) :
+ ZypperBaseCommand(
+ commandAliases_r,
+ _("refresh-services (refs) [OPTIONS]"),
+ _("Refresh all services."),
+ _("Refresh defined repository index services."))
+{
+
+}
+
+std::vector<BaseCommandConditionPtr> RefreshServicesCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
+
+ZyppFlags::CommandGroup RefreshServicesCmd::cmdOptions() const
+{
+ auto that = const_cast<RefreshServicesCmd *>(this);
+ return {{
+ { "force", 'f', ZyppFlags::NoArgument, ZyppFlags::BoolType( &that->_force, ZyppFlags::StoreTrue, _force), _("Force a complete refresh.") },
+ { "with-repos", 'r', ZyppFlags::NoArgument, ZyppFlags::BoolType( &that->_withRepos, ZyppFlags::StoreTrue, _withRepos), _("Refresh also the service repositories.") },
+ { "restore-status", 'R', ZyppFlags::NoArgument, ZyppFlags::BoolType( &that->_restoreStatus, ZyppFlags::StoreTrue, _restoreStatus), _("Also restore service repositories enabled/disabled state.") }
+ }};
+}
+
+void RefreshServicesCmd::doReset()
+{
+ _force = false;
+ _withRepos = false;
+ _restoreStatus = false;
+}
+
+int RefreshServicesCmd::execute( Zypper &zypper, const std::vector<std::string> &positionalArgs )
+{
+ return refreshServices( zypper );
+}
+
+int RefreshServicesCmd::refreshServices( Zypper &zypper )
+{
+ MIL << "going to refresh services" << endl;
+
+ ServiceList services = get_all_services( zypper );
+
+ // get the list of repos specified on the command line ...
+ ServiceList specified;
+ std::list<std::string> not_found;
+ // ...as command arguments
+ get_services( zypper, zypper.arguments().begin(), zypper.arguments().end(), specified, not_found );
+ report_unknown_services( zypper.out(), not_found ) ;
+
+ unsigned error_count = 0;
+ unsigned enabled_service_count = services.size();
+
+ if ( !specified.empty() || not_found.empty() )
+ {
+ unsigned number = 0;
+ for_( sit, services.begin(), services.end() )
+ {
+ ++number;
+ repo::RepoInfoBase_Ptr service_ptr( *sit );
+
+ // skip services not specified on the command line
+ if ( !specified.empty() )
+ {
+ bool found = false;
+ for_( it, specified.begin(), specified.end() )
+ if ( (*it)->alias() == service_ptr->alias() )
+ {
+ found = true;
+ break;
+ }
+
+ if ( !found )
+ {
+ DBG << service_ptr->alias() << "(#" << number << ") not specified," << " skipping." << endl;
+ --enabled_service_count;
+ continue;
+ }
+ }
+
+ // skip disabled services
+ if ( !service_ptr->enabled() )
+ {
+ DBG << "skipping disabled service '" << service_ptr->alias() << "'" << endl;
+
+ std::string msg = str::Format(_("Skipping disabled service '%s'")) % service_ptr->asUserString();
+ if ( specified.empty() )
+ zypper.out().info( msg, Out::HIGH );
+ else
+ zypper.out().error( msg );
+
+ --enabled_service_count;
+ continue;
+ }
+
+ // do the refresh
+ bool error = false;
+ ServiceInfo_Ptr s = dynamic_pointer_cast<ServiceInfo>(service_ptr);
+ if ( s )
+ {
+ RepoManager::RefreshServiceOptions opts;
+ if ( _restoreStatus )
+ opts |= RepoManager::RefreshService_restoreStatus;
+ if ( _force )
+ opts |= RepoManager::RefreshService_forceRefresh;
+
+ error = refresh_service( zypper, *s, opts );
+
+ // refresh also service's repos
+ if ( _withRepos )
+ {
+ RepoCollector collector;
+ RepoManager & rm = zypper.repoManager();
+ rm.getRepositoriesInService( s->alias(),
+ make_function_output_iterator( bind( &RepoCollector::collect, &collector, _1 ) ) );
+ for_( repoit, collector.repos.begin(), collector.repos.end() )
+ RefreshRepoCmd::refreshRepository( zypper, *repoit, _force ? RefreshRepoCmd::Force : RefreshRepoCmd::Default );
+ }
+ }
+ else
+ {
+ if ( !_withRepos )
+ {
+ DBG << "Skipping non-index service '" << service_ptr->asUserString() << "' because '--no-repos' is used.";
+ continue;
+ }
+ error = RefreshRepoCmd::refreshRepository( zypper, *dynamic_pointer_cast<RepoInfo>(service_ptr), _force ? RefreshRepoCmd::Force : RefreshRepoCmd::Default );
+ }
+
+ if ( error )
+ {
+ ERR << "Skipping service '" << service_ptr->alias() << "' because of the above error." << endl;
+ zypper.out().error( str::Format(_("Skipping service '%s' because of the above error.")) % service_ptr->asUserString().c_str() );
+ ++error_count;
+ }
+ }
+ }
+ else
+ enabled_service_count = 0;
+
+ // print the result message
+ if ( enabled_service_count == 0 )
+ {
+ std::string hint = str::form(_("Use '%s' or '%s' commands to add or enable services."),
+ "zypper addservice", "zypper modifyservice" );
+ if ( !specified.empty() || !not_found.empty() )
+ zypper.out().error(_("Specified services are not enabled or defined."), hint);
+ else
+ zypper.out().error(_("There are no enabled services defined."), hint);
+ }
+ else if ( error_count == enabled_service_count )
+ {
+ zypper.out().error(_("Could not refresh the services because of errors.") );
+ return ZYPPER_EXIT_ERR_ZYPP;
+ }
+ else if ( error_count )
+ {
+ zypper.out().error(_("Some of the services have not been refreshed because of an error.") );
+ return ZYPPER_EXIT_ERR_ZYPP;
+ }
+ else if ( !specified.empty() )
+ zypper.out().info(_("Specified services have been refreshed.") );
+ else
+ zypper.out().info(_("All services have been refreshed.") );
+
+ MIL << "DONE";
+ return ZYPPER_EXIT_OK;
+}
+
+
+int RefreshServicesCmd::systemSetup(Zypper &zypp_r)
+{
+ int code = defaultSystemSetup( zypp_r, InitTarget );
+ if ( code != ZYPPER_EXIT_OK )
+ return code;
+
+ zypp_r.globalOptsNoConst().rm_options.servicesTargetDistro =
+ zyppApi()->target()->targetDistribution();
+
+ return defaultSystemSetup( zypp_r, ResetRepoManager );
+}
+
+void RefreshServicesCmd::setRestoreStatus(bool restoreStatus)
+{
+ _restoreStatus = restoreStatus;
+}
+
+void RefreshServicesCmd::setWithRepos(bool withRepos)
+{
+ _withRepos = withRepos;
+}
+
+void RefreshServicesCmd::setForce(bool force)
+{
+ _force = force;
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_SERVICES_REFRESH_H_INCLUDED
+#define ZYPPER_COMMANDS_SERVICES_REFRESH_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "utils/flags/zyppflags.h"
+
+#include <zypp/base/Flags.h>
+
+class RefreshServicesCmd : public ZypperBaseCommand
+{
+
+public:
+ RefreshServicesCmd ( const std::vector<std::string> &commandAliases_r );
+
+ int refreshServices ( Zypper &zypper );
+
+ void setForce(bool force);
+ void setWithRepos(bool withRepos);
+ void setRestoreStatus(bool restoreStatus);
+
+ // ZypperBaseCommand interface
+protected:
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypper, const std::vector<std::string> &positionalArgs) override;
+ int systemSetup(Zypper &zypp_r) override;
+
+private:
+ bool _force = false;
+ bool _withRepos = false;
+ bool _restoreStatus = false;
+};
+
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#include "remove.h"
+#include "repos.h"
+
+#include "commands/conditions.h"
+#include "commands/services/common.h"
+
+#include "utils/misc.h"
+#include "utils/messages.h"
+#include "utils/flags/flagtypes.h"
+
+RemoveServiceCmd::RemoveServiceCmd(const std::vector<std::string> &commandAliases_r)
+ : ZypperBaseCommand (
+ commandAliases_r,
+ _("removeservice (rs) [OPTIONS] <ALIAS|#|URI>"),
+ _("Remove specified service."),
+ _("Remove specified repository index service from the system."),
+ ResetRepoManager
+ )
+{ }
+
+std::vector<BaseCommandConditionPtr> RemoveServiceCmd::conditions() const
+{
+ return {
+ std::make_shared<NeedsRootCondition>()
+ };
+}
+
+zypp::ZyppFlags::CommandGroup RemoveServiceCmd::cmdOptions() const
+{
+ auto that = const_cast<RemoveServiceCmd *>(this);
+ return {{{
+ { "loose-auth", '\0', ZyppFlags::NoArgument, ZyppFlags::BoolType( &that->_looseAuth, ZyppFlags::StoreTrue),
+ // translators: --loose-auth
+ _("Ignore user authentication data in the URI.")
+ },{ "loose-query", '\0', ZyppFlags::NoArgument, ZyppFlags::BoolType( &that->_looseQuery, ZyppFlags::StoreTrue),
+ // translators: --loose-query
+ _("Ignore query string in the URI.")
+ }
+ }}};
+}
+
+void RemoveServiceCmd::doReset()
+{
+ _looseAuth = false;
+ _looseQuery = false;
+}
+
+int RemoveServiceCmd::execute(Zypper &zypp, const std::vector<std::string> &positionalArgs)
+{
+ if ( positionalArgs.size() < 1)
+ {
+ ERR << "Required argument missing." << endl;
+ report_required_arg_missing( zypp.out(), help() );
+ return ZYPPER_EXIT_ERR_INVALID_ARGS;
+ }
+
+ std::set<repo::RepoInfoBase_Ptr, ServiceAliasComparator> to_remove;
+ for_(it, positionalArgs.begin(), positionalArgs.end())
+ {
+ repo::RepoInfoBase_Ptr s;
+ if (match_service( zypp, *it, s, _looseAuth, _looseQuery))
+ {
+ to_remove.insert(s);
+ }
+ else
+ {
+ MIL << "Service not found by given alias, number or URI." << endl;
+ // translators: %s is the supplied command line argument which
+ // for which no service counterpart was found
+ zypp.out().error( str::Format(_("Service '%s' not found by alias, number or URI.")) % *it );
+ }
+ }
+
+ for_(it, to_remove.begin(), to_remove.end())
+ {
+ RepoInfo_Ptr repo_ptr = dynamic_pointer_cast<RepoInfo>(*it);
+ if (repo_ptr)
+ remove_repo(zypp, *repo_ptr);
+ else
+ remove_service(zypp, *dynamic_pointer_cast<ServiceInfo>(*it));
+ }
+ return ZYPPER_EXIT_OK;
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+ ____ _ _ __ _ __ ___ _ _
+ |_ / || | '_ \ '_ \/ -_) '_|
+ /__|\_, | .__/ .__/\___|_|
+ |__/|_| |_|
+\*---------------------------------------------------------------------------*/
+#ifndef ZYPPER_COMMANDS_SERVICES_REMOVE_H_INCLUDED
+#define ZYPPER_COMMANDS_SERVICES_REMOVE_H_INCLUDED
+
+#include "commands/basecommand.h"
+#include "utils/flags/zyppflags.h"
+
+#include <zypp/base/Flags.h>
+
+class RemoveServiceCmd : public ZypperBaseCommand
+{
+public:
+ RemoveServiceCmd( const std::vector<std::string> &commandAliases_r );
+ // ZypperBaseCommand interface
+protected:
+ std::vector<BaseCommandConditionPtr> conditions() const override;
+ zypp::ZyppFlags::CommandGroup cmdOptions() const override;
+ void doReset() override;
+ int execute(Zypper &zypp, const std::vector<std::string> &positionalArgs) override;
+
+private:
+ bool _looseAuth = false;
+ bool _looseQuery = false;
+};
+
+#endif
+++ /dev/null
-#include <iostream>
-#include <boost/lexical_cast.hpp>
-
-#include <zypp/base/String.h>
-#include <zypp/base/Logger.h>
-#include <zypp/Locks.h>
-
-#include "output/Out.h"
-#include "main.h"
-#include "Table.h"
-#include "utils/misc.h"
-#include "locks.h"
-#include "repos.h"
-
-using namespace zypp;
-
-
-template <typename Target, typename Source>
-void safe_lexical_cast (Source s, Target &tr) {
- try {
- tr = boost::lexical_cast<Target> (s);
- }
- catch (boost::bad_lexical_cast &) {
- }
-}
-
-void add_locks(Zypper & zypper, const Zypper::ArgList & args, const ResKindSet & kinds)
-{
- try
- {
- Locks & locks = Locks::instance();
- locks.read(Pathname::assertprefix
- (zypper.globalOpts().root_dir, ZConfig::instance().locksFile()));
- Locks::size_type start = locks.size();
- for_(it,args.begin(),args.end())
- {
- PoolQuery q;
- if ( kinds.empty() ) // derive it from the name
- {
- sat::Solvable::SplitIdent split( *it );
- q.addAttribute( sat::SolvAttr::name, split.name().asString() );
- q.addKind( split.kind() );
- }
- else
- {
- q.addAttribute(sat::SolvAttr::name, *it);
- for_(itk, kinds.begin(), kinds.end()) {
- q.addKind(*itk);
- }
- }
- q.setMatchGlob();
- parsed_opts::const_iterator itr;
- //TODO rug compatibility for more arguments with version restrict
- if ((itr = copts.find("repo")) != copts.end())
- {
- for_(it_repo,itr->second.begin(), itr->second.end())
- {
- RepoInfo info;
- if( match_repo( zypper, *it_repo, &info))
- q.addRepo(info.alias());
- else //TODO some error handling
- WAR << "unknown repository" << *it_repo << endl;
- }
- }
- q.setCaseSensitive();
-
- locks.addLock(q);
- }
- locks.save(Pathname::assertprefix
- (zypper.globalOpts().root_dir, ZConfig::instance().locksFile()));
- if ( start != Locks::instance().size() )
- zypper.out().info(PL_(
- "Specified lock has been successfully added.",
- "Specified locks have been successfully added.",
- Locks::instance().size() - start));
- }
- catch(const Exception & e)
- {
- ZYPP_CAUGHT(e);
- zypper.out().error(e, _("Problem adding the package lock:"));
- zypper.setExitCode(ZYPPER_EXIT_ERR_ZYPP);
- }
-}
-
-
-void remove_locks(Zypper & zypper, const Zypper::ArgList & args, const ResKindSet & kinds)
-{
- try
- {
- Locks & locks = Locks::instance();
- locks.read(Pathname::assertprefix
- (zypper.globalOpts().root_dir, ZConfig::instance().locksFile()));
- Locks::size_type start = locks.size();
- for_( args_it, args.begin(), args.end() )
- {
- Locks::const_iterator it = locks.begin();
- Locks::LockList::size_type i = 0;
- safe_lexical_cast(*args_it, i);
- if (i > 0 && i <= locks.size())
- {
- advance(it, i-1);
- locks.removeLock(*it);
-
- zypper.out().info(_("Specified lock has been successfully removed."));
- }
- else //package name
- {
- //TODO fill query in one method to have consistent add/remove
- //TODO what to do with repo and kinds?
- PoolQuery q;
- if ( kinds.empty() ) // derive it from the name
- {
- // derive kind from the name: (rl should also support -t)
- sat::Solvable::SplitIdent split( *args_it );
- q.addAttribute( sat::SolvAttr::name, split.name().asString() );
- q.addKind( split.kind() );
- }
- else
- {
- q.addAttribute(sat::SolvAttr::name, *args_it);
- for_(itk, kinds.begin(), kinds.end()) {
- q.addKind(*itk);
- }
- }
- q.setMatchGlob();
- parsed_opts::const_iterator itr;
- if ((itr = copts.find("repo")) != copts.end())
- {
- for_(it_repo,itr->second.begin(), itr->second.end())
- {
- RepoInfo info;
- if( match_repo( zypper, *it_repo, &info))
- q.addRepo(info.alias());
- else //TODO some error handling
- WAR << "unknown repository" << *it_repo << endl;
- }
- }
- q.setCaseSensitive();
-
- locks.removeLock(q);
- }
- }
-
- locks.save(Pathname::assertprefix
- (zypper.globalOpts().root_dir, ZConfig::instance().locksFile()));
-
- // nothing removed
- if (start == locks.size())
- zypper.out().info(_("No lock has been removed."));
- //removed something
- else
- zypper.out().info(str::form(PL_(
- "%zu lock has been successfully removed.",
- "%zu locks have been successfully removed.",
- start - locks.size()), start - locks.size()));
- }
- catch(const Exception & e)
- {
- ZYPP_CAUGHT(e);
- zypper.out().error(e, _("Problem removing the package lock:"));
- zypper.setExitCode(ZYPPER_EXIT_ERR_ZYPP);
- }
-}
+++ /dev/null
-#ifndef ZYPPERLOCKS_H_
-#define ZYPPERLOCKS_H_
-
-#include "Zypper.h"
-
-void add_locks(Zypper & zypper, const Zypper::ArgList & args, const ResKindSet & kinds);
-void remove_locks(Zypper & zypper, const Zypper::ArgList & args, const ResKindSet & kinds);
-
-#endif /*ZYPPERLOCKS_H_*/
+++ /dev/null
-/*---------------------------------------------------------------------------*\
- ____ _ _ __ _ __ ___ _ _
- |_ / || | '_ \ '_ \/ -_) '_|
- /__|\_, | .__/ .__/\___|_|
- |__/|_| |_|
-\*---------------------------------------------------------------------------*/
-
-#include <iostream>
-
-#include <zypp/base/LogTools.h>
-#include <zypp/ExternalProgram.h>
-#include <zypp/misc/CheckAccessDeleted.h>
-
-#include "Zypper.h"
-#include "Table.h"
-#include "ps.h"
-
-///////////////////////////////////////////////////////////////////
-// PsOptions
-///////////////////////////////////////////////////////////////////
-
-inline std::ostream & operator<<( std::ostream & str, const PsOptions & obj )
-{ return str << "PsOptions"; }
-
-///////////////////////////////////////////////////////////////////
-namespace
-{
- ///////////////////////////////////////////////////////////////////
- /// \class PsImpl
- /// \brief Implementation of ps
- ///////////////////////////////////////////////////////////////////
- class PsImpl : public CommandBase<PsImpl,PsOptions>
- {
- typedef CommandBase<PsImpl,PsOptions> CommandBase;
- public:
- PsImpl( Zypper & zypper_r ) : CommandBase( zypper_r ) {}
- // CommandBase::_zypper
- // CommandBase::options; // access/manip command options
- // CommandBase::run; // action + catch and repost Out::Error
- // CommandBase::execute; // run + final "Done"/"Finished with error" message
- // CommandBase::showHelp; // Show user help on command
- public:
- /** default action */
- void action();
-
- private:
- void printServiceNamesOnly();
- };
- ///////////////////////////////////////////////////////////////////
-
- inline void loadData( CheckAccessDeleted & checker_r )
- {
- try
- {
- checker_r.check();
- }
- catch ( const Exception & ex )
- {
- throw( Out::Error( ZYPPER_EXIT_ERR_ZYPP, _("Check failed:"), ex ) );
- }
- }
-
- void PsImpl::printServiceNamesOnly()
- {
- CheckAccessDeleted checker( false ); // wait for explicit call to check()
- loadData( checker );
-
- std::set<std::string> services;
- for ( const auto & procInfo : checker )
- {
- std::string service( procInfo.service() );
- if ( ! service.empty() )
- services.insert( std::move(service) );
- }
-
- const std::string & format( options()._format );
- if ( format.empty() || format == "%s" )
- {
- for ( const auto & service : services )
- { cout << service << endl; }
- }
- else
- {
- for ( const auto & service : services )
- { cout << str::gsub( format, "%s", service ) << endl; }
- }
- }
-
- /**
- * fate #300763
- * Used by 'zypper ps' to show running processes that use
- * libraries or other files that have been removed since their execution.
- * This is particularly useful after 'zypper remove' or 'zypper update'.
- */
- void PsImpl::action()
- {
- if ( options().printServiceNamesOnly() )
- {
- // non table output of service names only
- return printServiceNamesOnly();
- }
-
- // Here: Table output
- _zypper.out().info(_("Checking for running processes using deleted libraries..."), Out::HIGH );
- CheckAccessDeleted checker( false ); // wait for explicit call to check()
-
- if(options().debugEnabled())
- checker.setDebugOutputFile(options()._debugFile);
-
- loadData( checker );
-
- Table t;
- bool tableWithFiles = options().tableWithFiles();
- bool tableWithNonServiceProcs = options().tableWithNonServiceProcs();
- t.allowAbbrev(6);
- {
- TableHeader th;
- // process ID
- th << _("PID")
- // parent process ID
- << _("PPID")
- // process user ID
- << _("UID")
- // process login name
- << _("User")
- // process command name
- << _("Command")
- // "/etc/init.d/ script that might be used to restart the command (guessed)
- << _("Service");
- if ( tableWithFiles )
- {
- // "list of deleted files or libraries accessed"
- th << _("Files");
- }
- t << std::move(th);
- }
-
- for ( const auto & procInfo : checker )
- {
- std::string service( procInfo.service() );
- if ( ! tableWithNonServiceProcs && service.empty() )
- continue;
-
- TableRow tr;
- tr << procInfo.pid << procInfo.ppid << procInfo.puid << procInfo.login << procInfo.command << std::move(service);
-
- if ( tableWithFiles )
- {
- std::vector<std::string>::const_iterator fit = procInfo.files.begin();
- tr << (fit != procInfo.files.end() ? *fit : "");
- t << std::move(tr);
-
- for ( ++fit; fit != procInfo.files.end(); ++fit )
- { t << ( TableRow() << "" << "" << "" << "" << "" << "" << *fit ); }
- }
- else
- {
- t << std::move(tr);
- }
- }
-
- if ( t.empty() )
- {
- _zypper.out().info(_("No processes using deleted files found.") );
- }
- else
- {
- _zypper.out().info(_("The following running processes use deleted files:") );
- cout << endl;
- cout << t << endl;
- _zypper.out().info(_("You may wish to restart these processes.") );
- _zypper.out().info( str::form( _("See '%s' for information about the meaning of values in the above table."),
- "man zypper" ) );
- }
-
- if ( geteuid() != 0 )
- {
- _zypper.out().info("");
- _zypper.out().info(_("Note: Not running as root you are limited to searching for files you have permission to examine with the system stat(2) function. The result might be incomplete."));
- }
- }
-} // namespace
-///////////////////////////////////////////////////////////////////
-
-int ps( Zypper & zypper_r )
-{
- return PsImpl( zypper_r ).run(); // no final "Done"/"Finished with error." message!
-}
+++ /dev/null
-/*---------------------------------------------------------------------------*\
- ____ _ _ __ _ __ ___ _ _
- |_ / || | '_ \ '_ \/ -_) '_|
- /__|\_, | .__/ .__/\___|_|
- |__/|_| |_|
-\*---------------------------------------------------------------------------*/
-#ifndef ZYPPER_PS_H
-#define ZYPPER_PS_H
-
-#include <string>
-class Zypper;
-
-/*
- ps ...
-*/
-
-/** ps specific options */
-struct PsOptions : public MixinOptions<ZypperCommand::PS>
-{
- PsOptions()
- : _shortness( 0 )
- {}
-
- unsigned _shortness; //< 1:wo file, 2:only proc with services, 3:service names only
- std::string _format; //< format string for --print / shortness 3
- std::string _debugFile; //< file name for the --debugFile switch
-
- bool tableWithFiles() const { return _shortness < 1; }
- bool tableWithNonServiceProcs() const { return _shortness < 2; }
- bool printServiceNamesOnly() const { return _shortness >= 3; }
- bool debugEnabled() const {return (!_debugFile.empty());}
-};
-
-/** Execute ps.
- */
-int ps( Zypper & zypper_r );
-
-#endif // ZYPPER_PS_H
#include <iterator>
#include <list>
-#include <boost/lexical_cast.hpp>
-
#include <zypp/ZYpp.h>
#include <zypp/base/Logger.h>
#include <zypp/base/IOStream.h>
#include "utils/misc.h"
#include "repos.h"
+//@TODO REMOVEME
+#include "commands/services/common.h"
+
extern ZYpp::Ptr God;
namespace zypp { using repo::RepoInfoBase_Ptr; }
typedef std::list<RepoInfoBase_Ptr> ServiceList;
typedef std::set<RepoInfo, RepoInfoAliasComparator> RepoInfoSet;
-static bool refresh_service( Zypper & zypper, const ServiceInfo & service );
-static RepoInfoSet collect_repos_by_option( Zypper & zypper );
+static RepoInfoSet collect_repos_by_option( Zypper & zypper, const RepoServiceCommonSelectOptions &selectOpts );
+
// ----------------------------------------------------------------------------
return( prio_r < RepoInfo::defaultPriority() ? _("raised priority") : _("lowered priority") );
}
-inline ColorString repoPriorityNumber( unsigned prio_r, int width_r = 0 )
+ColorString repoPriorityNumber( unsigned prio_r, int width_r )
{ return ColorString( repoPriorityColor( prio_r ), str::numstring( prio_r, width_r ) ); }
-inline ColorString repoPriorityNumberAnnotated( unsigned prio_r, int width_r = 0 )
+ColorString repoPriorityNumberAnnotated( unsigned prio_r, int width_r )
{ return repoPriorityNumber( prio_r, width_r ) << " (" << repoPriorityAnnotationStr( prio_r ) << ")"; }
// ----------------------------------------------------------------------------
-inline const char * repoAutorefreshStr( const repo::RepoInfoBase & repo_r )
+const char * repoAutorefreshStr( const repo::RepoInfoBase & repo_r )
{
static std::string dashes( LOWLIGHTString( "----" ).str() );
return( repo_r.enabled() ? asYesNo( repo_r.autorefresh() ) : dashes.c_str() );
// ----------------------------------------------------------------------------
-template <typename Target, typename Source>
-void safe_lexical_cast( Source s, Target & tr )
-{
- try
- {
- tr = boost::lexical_cast<Target>( s );
- }
- catch ( boost::bad_lexical_cast & )
- {;}
-}
-
-unsigned parse_priority( Zypper & zypper )
+unsigned parse_priority( const std::string &prio_r, std::string &error_r )
{
//! \todo use some preset priorities (high, medium, low, ...)
unsigned ret = 0U;
- parsed_opts::const_iterator cArg = zypper.cOpts().find( "priority" );
- if ( cArg == zypper.cOpts().end() )
+
+ if ( prio_r.empty() )
return ret; // 0: no --priority arg
int prio = -1;
- std::string prio_str = *cArg->second.begin();
- safe_lexical_cast( prio_str, prio ); // try to make an int out of the string
+ safe_lexical_cast( prio_r, prio ); // try to make an int out of the string
if ( prio < 0 )
{
- zypper.out().error(
+ error_r =
str::Format(_("Invalid priority '%s'. Use a positive integer number. The greater the number, the lower the priority."))
- % prio_str
- );
- zypper.setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- ZYPP_THROW( ExitRequestException("Invalid priority.") );
+ % prio_r;
+ ZYPP_THROW( Exception("Invalid priority.") );
}
ret = ( prio ? unsigned(prio) : RepoInfo::defaultPriority() );
return ret;
}
-// | Enabled | GPG Check | Colored strings for enabled and GPG Check status
-// +---------+-----------+
-// | Yes | ( ) No |
-// | Yes | (rp) Yes |
-// | No | ---- |
-struct RepoGpgCheckStrings
-{
- RepoGpgCheckStrings()
+RepoGpgCheckStrings::RepoGpgCheckStrings()
: _tagColor( ColorContext::DEFAULT )
- {}
+{}
- RepoGpgCheckStrings( const ServiceInfo & service_r )
+RepoGpgCheckStrings::RepoGpgCheckStrings(const ServiceInfo &service_r)
+{
+ if ( service_r.enabled() )
{
- if ( service_r.enabled() )
- {
- _tagColor = ColorContext::DEFAULT;
- _enabledYN = ColorString( _tagColor, _("Yes") );
- _gpgCheckYN = ColorString( _tagColor, "----" );
- }
- else
- {
- _tagColor = ColorContext::LOWLIGHT;
- _enabledYN = ColorString( _tagColor, _("No") );
- _gpgCheckYN = ColorString( _tagColor, "----" );
- }
+ _tagColor = ColorContext::DEFAULT;
+ _enabledYN = ColorString( _tagColor, _("Yes") );
+ _gpgCheckYN = ColorString( _tagColor, "----" );
+ }
+ else
+ {
+ _tagColor = ColorContext::LOWLIGHT;
+ _enabledYN = ColorString( _tagColor, _("No") );
+ _gpgCheckYN = ColorString( _tagColor, "----" );
}
+}
- RepoGpgCheckStrings( const RepoInfo & repo_r )
+RepoGpgCheckStrings::RepoGpgCheckStrings(const RepoInfo &repo_r)
+{
+ if ( repo_r.enabled() )
{
- if ( repo_r.enabled() )
+ bool gpgOK = false;
+ std::string tagStr( "( ) " );
+ if ( repo_r.validRepoSignature() ) // is TriBool!
{
- bool gpgOK = false;
- std::string tagStr( "( ) " );
- if ( repo_r.validRepoSignature() ) // is TriBool!
- {
- gpgOK = true;
- tagStr[1] = 'r';
- }
- if ( repo_r.pkgGpgCheck() )
- {
- gpgOK = true;
- tagStr[2] = 'p';
- }
- _tagColor = gpgOK ? ColorContext::DEFAULT : ColorContext::NEGATIVE;
- _enabledYN = ColorString( ColorContext::DEFAULT, _("Yes") );
- _gpgCheckYN = ColorString( _tagColor, tagStr+asYesNo(gpgOK) );
+ gpgOK = true;
+ tagStr[1] = 'r';
}
- else
+ if ( repo_r.pkgGpgCheck() )
{
- _tagColor = ColorContext::LOWLIGHT;
- _enabledYN = ColorString( _tagColor, _("No") );
- _gpgCheckYN = ColorString( _tagColor, "----" );
+ gpgOK = true;
+ tagStr[2] = 'p';
}
+ _tagColor = gpgOK ? ColorContext::DEFAULT : ColorContext::NEGATIVE;
+ _enabledYN = ColorString( ColorContext::DEFAULT, _("Yes") );
+ _gpgCheckYN = ColorString( _tagColor, tagStr+asYesNo(gpgOK) );
}
- ColorContext _tagColor; ///< color according to enabled and GPG Check status
- ColorString _enabledYN; ///< colored enabled Yes/No
- ColorString _gpgCheckYN; ///< colored GPG Check status if enabled else "----"
-};
+ else
+ {
+ _tagColor = ColorContext::LOWLIGHT;
+ _enabledYN = ColorString( _tagColor, _("No") );
+ _gpgCheckYN = ColorString( _tagColor, "----" );
+ }
+}
void repoPrioSummary( Zypper & zypper )
{
// ----------------------------------------------------------------------------
-static bool refresh_raw_metadata( Zypper & zypper, const RepoInfo & repo, bool force_download )
+bool refresh_raw_metadata( Zypper & zypper, const RepoInfo & repo, bool force_download )
{
RuntimeData & gData( zypper.runtimeData() );
gData.current_repo = repo;
// ---------------------------------------------------------------------------
-static bool build_cache( Zypper & zypper, const RepoInfo & repo, bool force_build )
+bool build_cache( Zypper & zypper, const RepoInfo & repo, bool force_build )
{
if ( force_build )
zypper.out().info(_("Forcing building of repository cache") );
// ---------------------------------------------------------------------------
-bool match_repo( Zypper & zypper, std::string str, RepoInfo *repo )
+bool match_repo( Zypper & zypper, std::string str, RepoInfo *repo, bool looseQuery_r, bool looseAuth_r )
{
RepoManager & manager( zypper.repoManager() );
url::ViewOption urlview =
url::ViewOption::DEFAULTS + url::ViewOption::WITH_PASSWORD;
- if ( zypper.cOpts().count("loose-auth") )
+ if ( looseAuth_r ) // ( zypper.cOpts().count("loose-auth") )
{
urlview = urlview
- url::ViewOptions::WITH_PASSWORD
- url::ViewOptions::WITH_USERNAME;
}
- if ( zypper.cOpts().count("loose-query") )
+ if ( looseQuery_r ) // ( zypper.cOpts().count("loose-query") )
urlview = urlview - url::ViewOptions::WITH_QUERY_STR;
// need to do asString(withurlview) comparison here because the user-given
// ---------------------------------------------------------------------------
-/** \return true if aliases are equal, and all lhs urls can be found in rhs */
-static bool repo_cmp_alias_urls( const RepoInfo & lhs, const RepoInfo & rhs )
+bool repo_cmp_alias_urls(const RepoInfo &lhs, const RepoInfo &rhs)
{
bool equals = true;
{
if ( std::find( rhs.baseUrlsBegin(), rhs.baseUrlsEnd(), Url(*urlit) ) != rhs.baseUrlsEnd() )
urlfound = true;
- if ( !urlfound )
+ if ( !urlfound )
{
equals = false;
break;
const std::list<std::string>::const_iterator &,
std::list<RepoInfo> &, std::list<std::string> & );
+// Explicit instantiations required for other translation units:
+template void get_repos<std::vector<std::string>::const_iterator>( Zypper &,
+ const std::vector<std::string>::const_iterator &,
+ const std::vector<std::string>::const_iterator &,
+ std::list<RepoInfo> &, std::list<std::string> & );
+
// ---------------------------------------------------------------------------
-/**
- * Say "Repository %s not found" for all strings in \a not_found list.
- */
void report_unknown_repos( Out & out, const std::list<std::string> & not_found )
{
if ( not_found.empty() )
{
if ( s->enabled() && s->autorefresh() )
{
- refresh_service(zypper, *s);
+ //@TODO MICHAEL is this correct?
+ refresh_service( zypper, *s );
}
}
}
}
}
-// ----------------------------------------------------------------------------
-
-static void print_repo_list( Zypper & zypper, const std::list<RepoInfo> & repos )
-{
- Table tbl;
- bool all = zypper.cOpts().count("details");
- std::string list_cols = zypper.config().repo_list_columns;
- bool showalias = zypper.cOpts().count("alias")
- || zypper.cOpts().count("sort-by-alias")
- || list_cols.find_first_of("aA") != std::string::npos;
- bool showname = zypper.cOpts().count("name")
- || zypper.cOpts().count("sort-by-name")
- || list_cols.find_first_of("nN") != std::string::npos;
- bool showrefresh = zypper.cOpts().count("refresh")
- || list_cols.find_first_of("rR") != std::string::npos;
- bool showuri = zypper.cOpts().count("uri") || zypper.cOpts().count("url")
- || zypper.cOpts().count("sort-by-uri")
- || list_cols.find_first_of("uU") != std::string::npos;
- bool showprio = zypper.cOpts().count("priority")
- || zypper.cOpts().count("sort-by-priority")
- || list_cols.find_first_of("pP") != std::string::npos;
- bool showservice = zypper.cOpts().count("service");
- bool sort_override = zypper.cOpts().count("sort-by-uri")
- || zypper.cOpts().count("sort-by-priority")
- || zypper.cOpts().count("sort-by-alias")
- || zypper.cOpts().count("sort-by-name");
- bool show_enabled_only = zypper.cOpts().count("show-enabled-only");
-
-
- // header
- TableHeader th;
- // keep count of columns so that we know which one to sort
- // TODO might be worth to improve Table to allow named columns so this can be avoided
- unsigned index = 0;
- // number of the column to sort by
- unsigned sort_index = 0;
-
- // repo number
- th << "#";
-
- // alias
- if ( all || showalias )
- {
- th << _("Alias");
- ++index;
- // if (zypper.cOpts().count("sort-by-alias")
- // || (list_cols.find("A") != std::string::npos && !sort_override))
- // sort by alias by default
- sort_index = index;
- }
-
- // name
- if ( all || showname )
- {
- th << _("Name");
- ++index;
- if ( zypper.cOpts().count("sort-by-name") || ( list_cols.find("N") != std::string::npos && !sort_override ) )
- sort_index = index;
- }
-
- // 'enabled' flag
- th << _("Enabled");
- ++index;
-
- // GPG Check
- th << _("GPG Check");
- ++index;
-
- // 'autorefresh' flag
- if ( all || showrefresh )
- {
- // translators: 'zypper repos' column - whether autorefresh is enabled
- // for the repository
- th << _("Refresh");
- ++index;
- if ( list_cols.find("R") != std::string::npos && !sort_override )
- sort_index = index;
- }
-
- // priority
- if ( all || showprio )
- {
- // translators: repository priority (in zypper repos -p or -d)
- th << _("Priority");
- ++index;
- if ( zypper.cOpts().count("sort-by-priority") || ( list_cols.find("P") != std::string::npos && !sort_override ) )
- sort_index = Table::UserData;
- }
-
- // type
- if ( all )
- {
- th << _("Type");
- ++index;
- }
-
- // URI
- if ( all || showuri )
- {
- th << _("URI");
- ++index;
- if ( zypper.cOpts().count("sort-by-uri") || ( list_cols.find("U") != std::string::npos && !sort_override ) )
- sort_index = index;
- }
-
- // service alias
- if ( all || showservice )
- {
- th << _("Service");
- ++index;
- }
-
- tbl << th;
-
- // table data
- int i = 0;
- unsigned nindent = repos.size() > 9 ? repos.size() > 99 ? 3 : 2 : 1;
- for_( it, repos.begin(), repos.end() )
- {
- ++i; // continuous numbering including skipped ones
- RepoInfo repo = *it;
-
- if ( show_enabled_only && !repo.enabled() )
- continue;
-
- TableRow tr( index );
- RepoGpgCheckStrings repoGpgCheck( repo ); // color strings for tag/enabled/gpgcheck
-
- // number
- tr << ColorString( repoGpgCheck._tagColor, str::numstring( i, nindent ) ).str();
- // alias
- if ( all || showalias ) tr << repo.alias();
- // name
- if ( all || showname ) tr << repo.name();
- // enabled?
- tr << repoGpgCheck._enabledYN.str();
- // GPG Check
- tr << repoGpgCheck._gpgCheckYN.str();
- // autorefresh?
- if ( all || showrefresh )
- tr << repoAutorefreshStr( repo );
- // priority
- if ( all || showprio )
- // output flush right; use custom sort index as coloring will break lex. sort
- ( tr << repoPriorityNumber( repo.priority(), 4 ) ).userData( repo.priority() );
- // type
- if ( all )
- tr << repo.type().asString();
- // url
- /**
- * \todo properly handle multiple baseurls - show "(multiple)"
- */
- if ( all || showuri )
- tr << (repo.baseUrlSet() ? repo.url().asString() : (repo.mirrorListUrl().asString().empty() ? "n/a" : repo.mirrorListUrl().asString()) );
-
- if ( all || showservice )
- tr << repo.service();
-
- tbl << tr;
- }
-
- if ( tbl.empty() )
- {
- zypper.out().warning(_("No repositories defined.") );
- zypper.out().info(_("Use the 'zypper addrepo' command to add one or more repositories.") );
- }
- else
- {
- if ( !showprio )
- {
- repoPrioSummary( zypper );
- zypper.out().gap();
- }
- // sort
- tbl.sort( sort_index );
- // print
- cout << tbl;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-static void print_repo_details( Zypper & zypper, std::list<RepoInfo> & repos )
-{
- bool first = true;
- for_( it, repos.begin(), repos.end() )
- {
- const RepoInfo & repo( *it );
-
- PropertyTable p;
- RepoGpgCheckStrings repoGpgCheck( repo );
-
- p.add( _("Alias"), repo.alias() );
- p.add( _("Name"), repo.name() );
- p.add( _("URI"), (repo.baseUrlSet()
- ? repo.url().asString()
- : (repo.mirrorListUrl().asString().empty()
- ? "n/a"
- : repo.mirrorListUrl().asString())) );
- p.add( _("Enabled"), repoGpgCheck._enabledYN.str() );
- p.add( _("GPG Check"), repoGpgCheck._gpgCheckYN.str() );
- p.add( _("Priority"), repoPriorityNumberAnnotated( repo.priority() ) );
- p.add( _("Autorefresh"), (repo.autorefresh() ? _("On") : _("Off")) );
- p.add( _("Keep Packages"), (repo.keepPackages() ? _("On") : _("Off")) );
- p.add( _("Type"), repo.type().asString() );
- p.add( _("GPG Key URI"), repo.gpgKeyUrl() );
- p.add( _("Path Prefix"), repo.path() );
- p.add( _("Parent Service"), repo.service() );
- p.lst( _("Keywords"), repo.contentKeywords() );
- p.add( _("Repo Info Path"), repo.filepath() );
- p.add( _("MD Cache Path"), repo.metadataPath() );
-
-
- if ( first )
- first = false;
- else
- cout << endl;
- cout << p;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-/** Repo list as xml */
-static void print_xml_repo_list( Zypper & zypper, std::list<RepoInfo> repos )
-{
- cout << "<repo-list>" << endl;
- for_( it, repos.begin(), repos.end() )
- it->dumpAsXmlOn( cout );
- cout << "</repo-list>" << endl;
-}
-
-// ----------------------------------------------------------------------------
-
-void print_repos_to( const std::list<RepoInfo> & repos, std::ostream & out )
+void clean_repos(Zypper & zypper , std::vector<std::string> specificRepos, CleanRepoFlags flags)
{
- for_( it, repos.begin(), repos.end() )
- it->dumpAsIniOn( out ) << endl;
-}
-
-// ----------------------------------------------------------------------------
+ RepoManager & manager( zypper.repoManager() );
-void list_repos( Zypper & zypper )
-{
- RepoManager & manager = zypper.repoManager();
- RuntimeData & gData = zypper.runtimeData();
std::list<RepoInfo> repos;
- std::list<std::string> not_found;
-
try
{
- if ( zypper.arguments().empty() )
- repos.insert( repos.end(), manager.repoBegin(), manager.repoEnd() );
- else
- {
- get_repos( zypper, zypper.arguments().begin(), zypper.arguments().end(), repos, not_found );
- report_unknown_repos( zypper.out(), not_found );
- }
+ repos.insert( repos.end(), manager.repoBegin(), manager.repoEnd() );
}
catch ( const Exception & e )
{
ZYPP_CAUGHT( e );
zypper.out().error( e, _("Error reading repositories:") );
- exit( ZYPPER_EXIT_ERR_ZYPP );
- }
-
- // add the temporary repos specified with the --plus-repo to the list
- if ( !gData.temporary_repos.empty() )
- repos.insert( repos.end(), gData.temporary_repos.begin(), gData.temporary_repos.end() );
-
- // export to file or stdout in repo file format
- /// \todo dedup writing code in list_services
- if ( copts.count("export") )
- {
- std::string filename_str = copts["export"].front();
- if ( filename_str == "-" )
- {
- print_repos_to(repos, cout);
- }
- else
- {
- if ( filename_str.rfind(".repo") == std::string::npos )
- filename_str += ".repo";
-
- Pathname file( filename_str );
- std::ofstream stream( file.c_str() );
- if ( !stream )
- {
- zypper.out().error( str::Format(_("Can't open %s for writing.")) % file.asString(),
- _("Maybe you do not have write permissions?") );
- exit( ZYPPER_EXIT_ERR_INVALID_ARGS );
- }
- else
- {
- print_repos_to( repos, stream );
- zypper.out().info( str::Format(_("Repositories have been successfully exported to %s.")) % file,
- Out::QUIET );
- }
- }
- }
- // print repo list as xml
- else if ( zypper.out().type() == Out::TYPE_XML )
- print_xml_repo_list( zypper, repos );
- else if ( !zypper.arguments().empty() )
- print_repo_details( zypper, repos );
- // print repo list as table
- else
- print_repo_list( zypper, repos );
-
- if ( !not_found.empty() ) {
- zypper.setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- } else if ( repos.empty() ) {
- zypper.setExitCode( ZYPPER_EXIT_NO_REPOS );
+ zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
+ return;
}
-}
-
-// ----------------------------------------------------------------------------
-
-void refresh_repos( Zypper & zypper )
-{
- MIL << "going to refresh repositories" << endl;
- // need gpg keys when downloading (#304672)
- init_target( zypper );
- RepoManager & manager( zypper.repoManager() );
- const std::list<RepoInfo> & repos( manager.knownRepositories() );
- // get the list of repos specified on the command line ...
+ // get the list of repos specified requested
std::list<RepoInfo> specified;
std::list<std::string> not_found;
- // ...as command arguments
- get_repos( zypper, zypper.arguments().begin(), zypper.arguments().end(), specified, not_found );
- // ...as --repo options
- parsed_opts::const_iterator tmp1( copts.find("repo") );
- if ( tmp1 != copts.end() )
- get_repos( zypper, tmp1->second.begin(), tmp1->second.end(), specified, not_found );
+ get_repos( zypper, specificRepos.begin(), specificRepos.end(), specified, not_found );
report_unknown_repos( zypper.out(), not_found );
- // --plus-content: It either specifies a known repo (by #, alias or URL)
- // or we need to also refresh all disabled repos to get their content
- // keywords.
- std::set<RepoInfo> plusContent;
- bool doContentCheck = false;
- for ( const std::string & spec : zypper.runtimeData().plusContentRepos )
- {
- RepoInfo r;
- if ( match_repo( zypper, spec, &r ) )
- plusContent.insert( r ); // specific repo: add to plusContent
- else if ( ! doContentCheck )
- doContentCheck = true; // keyword: need to scan all disabled repos
- }
-
std::ostringstream s;
s << _("Specified repositories: ");
for_( it, specified.begin(), specified.end() )
s << it->alias() << " ";
zypper.out().info( s.str(), Out::HIGH );
+ // should we clean packages or metadata ?
+ bool clean_all = flags.testFlag( CleanRepoBits::CleanAll );
+ bool clean_metadata = ( clean_all || flags.testFlag( CleanRepoBits::CleanMetaData ) );
+ bool clean_raw_metadata = ( clean_all || flags.testFlag( CleanRepoBits::CleanRawMetaData ) );
+ bool clean_packages = ( clean_all || !( clean_metadata || clean_raw_metadata ) );
+
+ DBG << "Metadata will be cleaned: " << clean_metadata << endl;
+ DBG << "Raw metadata will be cleaned: " << clean_raw_metadata << endl;
+ DBG << "Packages will be cleaned: " << clean_packages << endl;
+
unsigned error_count = 0;
unsigned enabled_repo_count = repos.size();
{
const RepoInfo & repo( *rit );
- if ( repo.enabled() )
+ if ( !specified.empty() )
{
- // enabled: Refreshed unless restricted by CLI args or mentioned in
- // --plus-content as specific repo.
- if ( !specified.empty() && std::find( specified.begin(), specified.end(), repo ) == specified.end() )
- {
- if ( plusContent.count( repo ) )
- {
- MIL << "[--plus-content] check " << repo.alias() << endl;
- zypper.out().info( str::Format(_("Refreshing repository '%s'.")) % repo.asUserString(),
- " [--plus-content]" );
- }
- else
- {
- DBG << repo.alias() << "(#" << ") not specified," << " skipping." << endl;
- enabled_repo_count--;
- continue;
- }
- }
+ bool found = false;
+ for_( it, specified.begin(), specified.end() )
+ if ( it->alias() == repo.alias() )
+ {
+ found = true;
+ break;
+ }
+
+ if ( !found )
+ {
+ DBG << repo.alias() << "(#" << ") not specified," << " skipping." << endl;
+ enabled_repo_count--;
+ continue;
+ }
}
- else
+
+ try
{
- // disabled: No refresh unless mentioned in --plus-content (specific or content check).
- // CLI args reffering to disabled repos are reported as error.
- if ( doContentCheck || plusContent.count( repo ) )
+ if( clean_metadata )
{
- MIL << "[--plus-content] check " << repo.alias() << endl;
- zypper.out().info( str::Format(_("Scanning content of disabled repository '%s'.")) % repo.asUserString(),
- " [--plus-content]" );
+ zypper.out().info( str::Format(_("Cleaning metadata cache for '%s'.")) % repo.asUserString(),
+ Out::HIGH );
+ manager.cleanCache( repo );
}
- else
+ if( clean_raw_metadata )
+ {
+ if ( ! repo.url().schemeIsVolatile() ) // cd/dvd
+ {
+ zypper.out().info( str::Format(_("Cleaning raw metadata cache for '%s'.")) % repo.asUserString(),
+ Out::HIGH );
+ manager.cleanMetadata( repo );
+ }
+ else
+ {
+ zypper.out().info( str::Format(_("Keeping raw metadata cache for %s '%s'.")) % repo.url().getScheme() % repo.asUserString(),
+ Out::HIGH );
+ }
+ }
+ if( clean_packages )
{
- if ( !specified.empty() && std::find( specified.begin(), specified.end(), repo ) == specified.end() )
- {
- DBG << repo.alias() << "(#" << ") not specified," << " skipping." << endl;
- }
- else
- {
- std::string msg( str::Format(_("Skipping disabled repository '%s'")) % repo.asUserString() );
-
- if ( specified.empty() )
- zypper.out().info( msg, Out::HIGH );
- else
- zypper.out().error( msg );
- }
- enabled_repo_count--;
- continue;
+ // translators: meaning the cached rpm files
+ zypper.out().info( str::Format(_("Cleaning packages for '%s'.")) % repo.asUserString(),
+ Out::HIGH );
+ manager.cleanPackages( repo );
}
}
-
- // do the refresh
- if ( refresh_repo( zypper, repo ) )
+ catch(...)
{
- zypper.out().error( str::Format(_("Skipping repository '%s' because of the above error.")) % repo.asUserString() );
- ERR << "Skipping repository '" << repo.alias() << "' because of the above error." << endl;
+ ERR << "Cannot clean repository '" << repo.alias() << "' because of an error." << endl;
+ zypper.out().error( str::Format(_("Cannot clean repository '%s' because of an error.")) % repo.asUserString() );
error_count++;
}
}
else
enabled_repo_count = 0;
- // print the result message
- if ( !not_found.empty() )
- {
- zypper.out().error(_("Some of the repositories have not been refreshed because they were not known.") );
- zypper.setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
- return;
- }
- else if ( enabled_repo_count == 0 )
+ // clean the target system cache
+ if( clean_metadata )
{
- if ( !specified.empty() )
- zypper.out().warning(_("Specified repositories are not enabled or defined.") );
- else {
- zypper.out().warning(_("There are no enabled repositories defined.") );
- zypper.setExitCode( ZYPPER_EXIT_NO_REPOS );
+ zypper.out().info(_("Cleaning installed packages cache."), Out::HIGH );
+ try
+ {
+ init_target( zypper );
+ God->target()->cleanCache();
+ }
+ catch (...)
+ {
+ ERR << "Couldn't clean @System cache" << endl;
+ zypper.out().error(_("Cannot clean installed packages cache because of an error.") );
+ error_count++;
}
-
- zypper.out().info( str::form(_("Use '%s' or '%s' commands to add or enable repositories."),
- "zypper addrepo", "zypper modifyrepo" ) );
}
- else if ( error_count == enabled_repo_count )
+
+ if ( specificRepos.empty() && clean_packages )
{
- zypper.out().error(_("Could not refresh the repositories because of errors.") );
- zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
- return;
- }
- else if ( error_count )
- {
- zypper.out().error(_("Some of the repositories have not been refreshed because of an error.") );
- zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
- return;
- }
- else if ( !specified.empty() )
- zypper.out().info(_("Specified repositories have been refreshed.") );
- else
- zypper.out().info(_("All repositories have been refreshed.") );
-}
-
-// ----------------------------------------------------------------------------
-
-/** \return false on success, true on error */
-bool refresh_repo( Zypper & zypper, const RepoInfo & repo )
-{
- MIL << "going to refresh repo '" << repo.alias() << "'" << endl;
-
- // raw metadata refresh
- bool error = false;
- if ( !zypper.cOpts().count("build-only") )
- {
- bool force_download = zypper.cOpts().count("force") || zypper.cOpts().count("force-download");
- MIL << "calling refreshMetadata" << (force_download ? ", forced" : "") << endl;
- error = refresh_raw_metadata( zypper, repo, force_download );
- }
-
- // db rebuild
- if ( !( error || zypper.cOpts().count("download-only") ) )
- {
- bool force_build = zypper.cOpts().count("force") || zypper.cOpts().count("force-build");
- MIL << "calling buildCache" << (force_build ? ", forced" : "") << endl;
- error = build_cache( zypper, repo, force_build );
- }
-
- return error;
-}
-
-// ----------------------------------------------------------------------------
-
-void clean_repos( Zypper & zypper )
-{
- RepoManager & manager( zypper.repoManager() );
-
- std::list<RepoInfo> repos;
- try
- {
- repos.insert( repos.end(), manager.repoBegin(), manager.repoEnd() );
- }
- catch ( const Exception & e )
- {
- ZYPP_CAUGHT( e );
- zypper.out().error( e, _("Error reading repositories:") );
- zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
- return;
- }
-
- // get the list of repos specified on the command line ...
- std::list<RepoInfo> specified;
- std::list<std::string> not_found;
- // ...as command arguments
- get_repos( zypper, zypper.arguments().begin(), zypper.arguments().end(), specified, not_found );
- // ...as --repo options
- parsed_opts::const_iterator tmp1;
- if ( (tmp1 = copts.find("repo")) != copts.end() )
- get_repos( zypper, tmp1->second.begin(), tmp1->second.end(), specified, not_found );
- report_unknown_repos( zypper.out(), not_found );
-
- std::ostringstream s;
- s << _("Specified repositories: ");
- for_( it, specified.begin(), specified.end() )
- s << it->alias() << " ";
- zypper.out().info( s.str(), Out::HIGH );
-
- // should we clean packages or metadata ?
- bool clean_all = copts.find("all") != copts.end();
- bool clean_metadata = ( clean_all || copts.find("metadata") != copts.end() );
- bool clean_raw_metadata = ( clean_all || copts.find("raw-metadata") != copts.end() );
- bool clean_packages = ( clean_all || !( clean_metadata || clean_raw_metadata ) );
-
- DBG << "Metadata will be cleaned: " << clean_metadata << endl;
- DBG << "Raw metadata will be cleaned: " << clean_raw_metadata << endl;
- DBG << "Packages will be cleaned: " << clean_packages << endl;
-
- unsigned error_count = 0;
- unsigned enabled_repo_count = repos.size();
-
- if ( !specified.empty() || not_found.empty() )
- {
- for_( rit, repos.begin(), repos.end() )
- {
- const RepoInfo & repo( *rit );
-
- if ( !specified.empty() )
- {
- bool found = false;
- for_( it, specified.begin(), specified.end() )
- if ( it->alias() == repo.alias() )
- {
- found = true;
- break;
- }
-
- if ( !found )
- {
- DBG << repo.alias() << "(#" << ") not specified," << " skipping." << endl;
- enabled_repo_count--;
- continue;
- }
- }
-
- try
- {
- if( clean_metadata )
- {
- zypper.out().info( str::Format(_("Cleaning metadata cache for '%s'.")) % repo.asUserString(),
- Out::HIGH );
- manager.cleanCache( repo );
- }
- if( clean_raw_metadata )
- {
- if ( ! repo.url().schemeIsVolatile() ) // cd/dvd
- {
- zypper.out().info( str::Format(_("Cleaning raw metadata cache for '%s'.")) % repo.asUserString(),
- Out::HIGH );
- manager.cleanMetadata( repo );
- }
- else
- {
- zypper.out().info( str::Format(_("Keeping raw metadata cache for %s '%s'.")) % repo.url().getScheme() % repo.asUserString(),
- Out::HIGH );
- }
- }
- if( clean_packages )
- {
- // translators: meaning the cached rpm files
- zypper.out().info( str::Format(_("Cleaning packages for '%s'.")) % repo.asUserString(),
- Out::HIGH );
- manager.cleanPackages( repo );
- }
- }
- catch(...)
- {
- ERR << "Cannot clean repository '" << repo.alias() << "' because of an error." << endl;
- zypper.out().error( str::Format(_("Cannot clean repository '%s' because of an error.")) % repo.asUserString() );
- error_count++;
- }
- }
- }
- else
- enabled_repo_count = 0;
-
- // clean the target system cache
- if( clean_metadata )
- {
- zypper.out().info(_("Cleaning installed packages cache."), Out::HIGH );
- try
- {
- init_target( zypper );
- God->target()->cleanCache();
- }
- catch (...)
- {
- ERR << "Couldn't clean @System cache" << endl;
- zypper.out().error(_("Cannot clean installed packages cache because of an error.") );
- error_count++;
- }
- }
-
- if ( zypper.arguments().empty() && clean_packages )
- {
- // clean up garbage
- // this could also be done with a special option or on each 'clean'
- // regardless of the options used ...
- manager.cleanCacheDirGarbage();
- // clean zypper's cache
- // this could also be done with a special option
- filesystem::recursive_rmdir( Pathname::assertprefix( zypper.globalOpts().root_dir, ZYPPER_RPM_CACHE_DIR ) );
+ // clean up garbage
+ // this could also be done with a special option or on each 'clean'
+ // regardless of the options used ...
+ manager.cleanCacheDirGarbage();
+ // clean zypper's cache
+ // this could also be done with a special option
+ filesystem::recursive_rmdir( Pathname::assertprefix( zypper.globalOpts().root_dir, ZYPPER_RPM_CACHE_DIR ) );
}
if ( enabled_repo_count > 0 && error_count >= enabled_repo_count )
// ----------------------------------------------------------------------------
-inline std::string timestamp()
-{ return Date::now().form("%Y%m%d-%H%M%S"); }
-
-// ----------------------------------------------------------------------------
-
-bool add_repo( Zypper & zypper, RepoInfo & repo )
+bool add_repo( Zypper & zypper, RepoInfo & repo, bool noCheck )
{
RepoManager & manager = zypper.repoManager();
RuntimeData & gData = zypper.runtimeData();
if ( is_cd )
{
- if ( ! copts.count("no-check") )
+ if ( ! noCheck )
{
zypper.out().info( str::Format(_("Reading data from '%s' media")) % repo.asUserString() );
bool error = refresh_raw_metadata( zypper, repo, false );
/// \todo merge common code with add_repo_from_file
void add_repo_by_url( Zypper & zypper,
const Url & url,
- const std::string & alias )
+ const std::string & alias,
+ const RepoServiceCommonOptions &opts,
+ const RepoProperties &repoProps,
+ bool noCheck )
{
MIL << "going to add repository by url (alias=" << alias << ", url=" << url << ")" << endl;
repo.addBaseUrl( url );
- parsed_opts::const_iterator it = zypper.cOpts().find("name");
- if ( it != zypper.cOpts().end() )
- repo.setName( it->second.front() );
+ if ( !opts._name.empty() )
+ repo.setName( opts._name );
- TriBool bopt = get_boolean_option( zypper, "enable", "disable" );
- repo.setEnabled( indeterminate(bopt) ? true : bool(bopt) );
+ repo.setEnabled( indeterminate( opts._enable ) ? true : bool(opts._enable) );
+ repo.setAutorefresh( indeterminate( opts._enableAutoRefresh ) ? false : bool( opts._enableAutoRefresh ) ); // wouldn't true be the better default?
- bopt = get_boolean_option( zypper, "refresh", "no-refresh" );
- repo.setAutorefresh( indeterminate(bopt) ? false : bool(bopt) ); // wouldn't true be the better default?
+ if ( repoProps._priority >= 1 )
+ repo.setPriority( repoProps._priority );
- unsigned prio = parse_priority( zypper );
- if ( prio >= 1 )
- repo.setPriority( prio );
+ if ( !indeterminate( repoProps._keepPackages ) )
+ repo.setKeepPackages( repoProps._keepPackages );
- bopt = get_boolean_option( zypper, "keep-packages", "no-keep-packages" );
- if ( !indeterminate(bopt) )
- repo.setKeepPackages( bopt );
-
- RepoInfo::GpgCheck gpgCheck( cli::gpgCheck( zypper ) );
+ RepoInfo::GpgCheck gpgCheck = repoProps._gpgCheck;
if ( gpgCheck != RepoInfo::GpgCheck::indeterminate )
repo.setGpgCheck( gpgCheck );
- if ( add_repo( zypper, repo ) )
+ if ( add_repo( zypper, repo, noCheck ) )
repoPrioSummary( zypper );
}
// ----------------------------------------------------------------------------
/// \todo merge common code with add_repo_by_url
void add_repo_from_file( Zypper & zypper,
- const std::string & repo_file_url )
+ const std::string & repo_file_url,
+ const RepoServiceCommonOptions &opts,
+ const RepoProperties &repoProps,
+ bool noCheck )
{
Url url = make_url( repo_file_url );
if ( !url.isValid() )
return;
}
- std::string name;
- if ( zypper.cOpts().count("name") )
- name = zypper.cOpts().find("name")->second.front();
-
- TriBool enabled = get_boolean_option( zypper, "enable", "disable" );
- TriBool autorefresh = get_boolean_option( zypper, "refresh", "no-refresh" );
- unsigned prio = parse_priority( zypper );
- TriBool keepPackages = get_boolean_option( zypper, "keep-packages", "no-keep-packages" );
- RepoInfo::GpgCheck gpgCheck( cli::gpgCheck( zypper ) );
+ RepoInfo::GpgCheck gpgCheck = repoProps._gpgCheck;
std::list<RepoInfo> repos;
continue;
}
- if ( ! name.empty() )
- repo.setName( name );
+ if ( ! opts._name.empty() )
+ repo.setName( opts._name );
- if ( !indeterminate(enabled) )
- repo.setEnabled( enabled );
+ if ( !indeterminate(opts._enable) )
+ repo.setEnabled( opts._enable );
- if ( !indeterminate(autorefresh) )
- repo.setAutorefresh( autorefresh );
+ if ( !indeterminate( opts._enableAutoRefresh) )
+ repo.setAutorefresh( opts._enableAutoRefresh );
- if ( !indeterminate(keepPackages) )
- repo.setKeepPackages( keepPackages );
+ if ( !indeterminate( repoProps._keepPackages ) )
+ repo.setKeepPackages( repoProps._keepPackages );
if ( gpgCheck != RepoInfo::GpgCheck::indeterminate )
repo.setGpgCheck( gpgCheck );
- if ( prio >= 1 )
- repo.setPriority( prio );
+ if ( repoProps._priority >= 1 )
+ repo.setPriority( repoProps._priority );
- if ( add_repo( zypper, repo ) )
+ if ( add_repo( zypper, repo, noCheck ) )
addedAtLeastOneRepository = true;
}
return;
}
+unsigned priority_from_copts( Zypper &zypper )
+{
+ unsigned prio = 0U;
+ parsed_opts::const_iterator cArg = zypper.cOpts().find( "priority" );
+ if ( cArg != zypper.cOpts().end() ) {
+ std::string err;
+ try {
+ prio = parse_priority( *cArg->second.begin(), err );
+ } catch ( const Exception &e ) {
+ zypper.out().error( err );
+ zypper.setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
+ ZYPP_THROW( ExitRequestException( e.asString() ) );
+ }
+ }
+ return prio;
+}
+
// ----------------------------------------------------------------------------
template<typename T>
}
// ----------------------------------------------------------------------------
-void remove_repos_by_option(Zypper &zypper)
+void remove_repos_by_option( Zypper &zypper_r, const RepoServiceCommonSelectOptions selOpts_r )
{
- RepoInfoSet repos = collect_repos_by_option( zypper );
+ RepoInfoSet repos = collect_repos_by_option( zypper_r, selOpts_r );
for ( const RepoInfo &repo : repos )
{
- remove_repo( zypper, repo );
+ remove_repo( zypper_r, repo );
}
}
// ----------------------------------------------------------------------------
-void rename_repo( Zypper & zypper, const std::string & alias, const std::string & newalias )
-{
- RepoManager & manager( zypper.repoManager() );
-
- try
- {
- RepoInfo repo( manager.getRepositoryInfo( alias ) );
-
- if ( !repo.service().empty() )
- {
- zypper.out().error(str::form(
- _("Cannot change alias of '%s' repository. The repository"
- " belongs to service '%s' which is responsible for setting its alias."),
- alias.c_str(), repo.service().c_str()));
- zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
- return;
- }
-
- repo.setAlias( newalias );
- manager.modifyRepository( alias, repo );
- MIL << "Repository '" << alias << "' renamed to '" << repo.alias() << "'" << endl;
- zypper.out().info( str::Format(_("Repository '%s' renamed to '%s'.")) % alias % repo.alias() );
- }
- catch ( const repo::RepoAlreadyExistsException & ex )
- {
- zypper.out().error( str::Format(_("Repository named '%s' already exists. Please use another alias.")) % newalias );
- }
- catch ( const Exception & ex )
- {
- ERR << "Error while modifying the repository " << ex.asUserString() << endl;
- zypper.out().error( ex, _("Error while modifying the repository:"),
- str::Format(_("Leaving repository '%s' unchanged.")) % alias );
- }
-}
// ----------------------------------------------------------------------------
-RepoInfoSet collect_repos_by_option( Zypper & zypper )
+
+RepoInfoSet collect_repos_by_option( Zypper & zypper, const RepoServiceCommonSelectOptions &selectOpts )
{
RepoManager & manager( zypper.repoManager() );
const std::list<RepoInfo> & repos( manager.knownRepositories() );
RepoInfoSet toModify;
- if ( copts.count("all") )
+ if ( selectOpts._all )
{
std::for_each( repos.begin(), repos.end(), [&toModify] (const RepoInfo &info) { toModify.insert( info ); } );
}
{
std::list<std::function<bool (const RepoInfo &)>> filterList;
- if ( copts.count("local") )
+ if ( selectOpts._local )
{
filterList.push_back([]( const RepoInfo &info ) {
return ( !info.baseUrlsEmpty() && !info.url().schemeIsDownloading() );
});
}
- if ( copts.count("remote") )
+ if ( selectOpts._remote )
{
filterList.push_back([]( const RepoInfo &info ) {
return ( !info.baseUrlsEmpty() && info.url().schemeIsDownloading() );
});
}
- if ( copts.count("medium-type") )
+ if ( selectOpts._mediumTypes.size() )
{
- filterList.push_back([]( const RepoInfo &info ) {
- const std::list<std::string> & pars = copts["medium-type"];
+ filterList.push_back([ &selectOpts ]( const RepoInfo &info ) {
+ const std::vector<std::string> & pars = selectOpts._mediumTypes;
return ( !info.baseUrlsEmpty() && std::find( pars.begin(), pars.end(), info.url().getScheme() ) != pars.end() );
});
}
return toModify;
}
-void modify_repos_by_option( Zypper & zypper )
+void modify_repos_by_option( Zypper & zypper, const RepoServiceCommonSelectOptions &selectOpts, const RepoServiceCommonOptions &commonOpts, const RepoProperties &repoProps )
{
- RepoInfoSet toModify = collect_repos_by_option( zypper );
+ RepoInfoSet toModify = collect_repos_by_option( zypper, selectOpts );
for_( it, toModify.begin(), toModify.end() )
{
- modify_repo( zypper, it->alias() );
+ modify_repo( zypper, it->alias(), commonOpts, repoProps );
}
}
// ----------------------------------------------------------------------------
-void modify_repo( Zypper & zypper, const std::string & alias )
+
+
+void modify_repo( Zypper & zypper, const std::string & alias, const RepoServiceCommonOptions &commonOpts, const RepoProperties &repoProps )
{
// enable/disable repo
- TriBool enable = get_boolean_option( zypper, "enable", "disable" );
+ const TriBool &enable = commonOpts._enable;
DBG << "enable = " << enable << endl;
// autorefresh
- TriBool autoref = get_boolean_option( zypper, "refresh", "no-refresh" );
+ const TriBool &autoref = commonOpts._enableAutoRefresh;
DBG << "autoref = " << autoref << endl;
- TriBool keepPackages = get_boolean_option( zypper, "keep-packages", "no-keep-packages" );
+ const TriBool &keepPackages = repoProps._keepPackages;
DBG << "keepPackages = " << keepPackages << endl;
- RepoInfo::GpgCheck gpgCheck( cli::gpgCheck( zypper ) );
+ const RepoInfo::GpgCheck &gpgCheck = repoProps._gpgCheck;
- unsigned prio = parse_priority( zypper );
+ unsigned prio = repoProps._priority;
try
{
}
}
- std::string name;
- parsed_opts::const_iterator tmp1;
- if ( (tmp1 = zypper.cOpts().find("name")) != zypper.cOpts().end() )
- {
- name = *tmp1->second.begin();
- if ( !name.empty() )
- repo.setName( name );
- }
+ const std::string &name = commonOpts._name;
+ if ( !name.empty() )
+ repo.setName( name );
if ( changed_enabled || changed_autoref || changed_prio
|| changed_keeppackages || changed_gpgcheck || !name.empty() )
// Service Handling
// ---------------------------------------------------------------------------
-static ServiceList get_all_services( Zypper & zypper )
-{
- RepoManager & manager( zypper.repoManager() );
- ServiceList services;
-
- try
- {
- // RIS type services
- for_( it, manager.serviceBegin(), manager.serviceEnd() )
- {
- services.insert( services.end(), ServiceInfo_Ptr( new ServiceInfo( *it ) ) ); // copy needed?
- }
-
- // non-services repos
- for_( it, manager.repoBegin(), manager.repoEnd() )
- {
- if ( !it->service().empty() )
- continue;
- services.insert( services.end(), RepoInfo_Ptr( new RepoInfo( *it ) ) ); // copy needed?
- }
- }
- catch ( const Exception &e )
- {
- ZYPP_CAUGHT(e);
- zypper.out().error( e, _("Error reading services:") );
- exit( ZYPPER_EXIT_ERR_ZYPP );
- }
- return services;
-}
+// ---------------------------------------------------------------------------
-bool match_service( Zypper & zypper, std::string str, RepoInfoBase_Ptr & service_ptr )
-{
- ServiceList known = get_all_services( zypper );
- bool found = false;
- unsigned number = 0; // service number start with 1
- for_( known_it, known.begin(), known.end() )
- {
- ++number;
- unsigned tmp = 0;
- safe_lexical_cast( str, tmp ); // try to make an int out of the string
- try
- {
- // match by alias or number
- found = (*known_it)->alias() == str || tmp == number;
+// ---------------------------------------------------------------------------
- // match by URL
- if ( !found )
- {
- url::ViewOption urlview = url::ViewOption::DEFAULTS + url::ViewOption::WITH_PASSWORD;
- if ( zypper.cOpts().count("loose-auth") )
- {
- urlview = urlview - url::ViewOptions::WITH_PASSWORD - url::ViewOptions::WITH_USERNAME;
- }
- if ( zypper.cOpts().count("loose-query") )
- urlview = urlview - url::ViewOptions::WITH_QUERY_STR;
+enum ServiceListFlagsBits
+{
+ SF_SHOW_ALL = 7,
+ SF_SHOW_URI = 1,
+ SF_SHOW_PRIO = 1 << 1,
+ SF_SHOW_WITH_REPOS = 1 << 2,
+ SF_SERVICE_REPO = 1 << 15
+};
+ZYPP_DECLARE_FLAGS( ServiceListFlags,ServiceListFlagsBits );
+ZYPP_DECLARE_OPERATORS_FOR_FLAGS( ServiceListFlags );
- ServiceInfo_Ptr s_ptr = dynamic_pointer_cast<ServiceInfo>(*known_it);
- if ( !( urlview.has(url::ViewOptions::WITH_PASSWORD) && urlview.has(url::ViewOptions::WITH_QUERY_STR) ) )
- {
- if ( s_ptr )
- found = Url(str).asString(urlview) == s_ptr->url().asString(urlview);
- else
- {
- RepoInfo_Ptr r_ptr = dynamic_pointer_cast<RepoInfo>(*known_it);
- if ( !r_ptr->baseUrlsEmpty() )
- {
- for_( urlit, r_ptr->baseUrlsBegin(), r_ptr->baseUrlsEnd() )
- if ( urlit->asString(urlview) == Url(str).asString(urlview) )
- {
- found = true;
- break;
- }
- }
- }
- }
- else
- {
- if ( s_ptr )
- found = ( Url(str) == s_ptr->url() );
- else
- {
- RepoInfo_Ptr r_ptr = dynamic_pointer_cast<RepoInfo>(*known_it);
- if ( !r_ptr->baseUrlsEmpty() )
- {
- found = find( r_ptr->baseUrlsBegin(), r_ptr->baseUrlsEnd(), Url(str) ) != r_ptr->baseUrlsEnd();
- }
- }
- }
- }
- if ( found )
- {
- service_ptr = *known_it;
- break;
- }
- }
- catch( const url::UrlException & )
- {}
+// ---------------------------------------------------------------------------
- } // END for all known services
- return found;
-}
-/**
- * Say "Service %s not found" for all strings in \a not_found list.
- */
-static void report_unknown_services( Out & out, std::list<std::string> not_found )
-{
- for_( it, not_found.begin(), not_found.end() )
- out.error( str::Format(_("Service '%s' not found by its alias, number, or URI.")) % *it );
-
- if ( !not_found.empty() )
- out.info( str::Format(_("Use '%s' to get the list of defined services.")) % "zypper repos" );
-}
-
-/**
- * Try to find ServiceInfo or RepoInfo counterparts among known services by alias, number,
- * or URI, based on the list of strings given as the iterator range \a begin and
- * \a end. Matching objects will be added to \a services (as RepoInfoBase_Ptr) and those
- * with no match will be added to \a not_found.
- */
-template<typename T>
-void get_services( Zypper & zypper, const T & begin, const T & end,
- ServiceList & services, std::list<std::string> & not_found )
-{
- for_( it, begin, end )
- {
- RepoInfoBase_Ptr service;
-
- if ( !match_service( zypper, *it, service ) )
- {
- not_found.push_back( *it );
- continue;
- }
-
- // service found
- // is it a duplicate? compare by alias and URIs
- //! \todo operator== in RepoInfo?
- bool duplicate = false;
- for_( serv_it, services.begin(), services.end() )
- {
- ServiceInfo_Ptr s_ptr = dynamic_pointer_cast<ServiceInfo>(*serv_it);
- ServiceInfo_Ptr current_service_ptr = dynamic_pointer_cast<ServiceInfo>(service);
-
- // one is a service, the other is a repo
- if ( s_ptr && !current_service_ptr )
- continue;
-
- // service
- if ( s_ptr )
- {
- if ( s_ptr->alias() == current_service_ptr->alias()
- && s_ptr->url() == current_service_ptr->url() )
- {
- duplicate = true;
- break;
- }
- }
- // repo
- else if ( repo_cmp_alias_urls( *dynamic_pointer_cast<RepoInfo>(service),
- *dynamic_pointer_cast<RepoInfo>(*serv_it) ) )
- {
- duplicate = true;
- break;
- }
- } // END for all found so far
-
- if ( !duplicate )
- services.push_back( service );
- }
-}
-
-// ---------------------------------------------------------------------------
-
-struct RepoCollector
-{
- bool collect( const RepoInfo & repo )
- {
- repos.push_back( repo );
- return true;
- }
- RepoInfoList repos;
-};
-
-// ---------------------------------------------------------------------------
-
-enum ServiceListFlagsBits
-{
- SF_SHOW_ALL = 7,
- SF_SHOW_URI = 1,
- SF_SHOW_PRIO = 1 << 1,
- SF_SHOW_WITH_REPOS = 1 << 2,
- SF_SERVICE_REPO = 1 << 15
-};
-ZYPP_DECLARE_FLAGS( ServiceListFlags,ServiceListFlagsBits );
-ZYPP_DECLARE_OPERATORS_FOR_FLAGS( ServiceListFlags );
-
-static void service_list_tr( Zypper & zypper,
- Table & tbl,
- const RepoInfoBase_Ptr & srv,
- unsigned reponumber,
- const ServiceListFlags & flags )
-{
- ServiceInfo_Ptr service = dynamic_pointer_cast<ServiceInfo>(srv);
- RepoInfo_Ptr repo;
- if ( ! service )
- repo = dynamic_pointer_cast<RepoInfo>(srv);
-
- RepoGpgCheckStrings repoGpgCheck( service ? RepoGpgCheckStrings(*service) : RepoGpgCheckStrings(*repo) );
-
- TableRow tr( 8 );
-
- // number
- if ( flags & SF_SERVICE_REPO )
- {
- if ( repo && ! repo->enabled() )
- tr << ColorString( repoGpgCheck._tagColor, "-" ).str();
- else
- tr << "";
- }
- else
- tr << ColorString( repoGpgCheck._tagColor, str::numstring(reponumber) ).str();
-
- // alias
- tr << srv->alias();
- // name
- tr << srv->name();
- // enabled?
- tr << repoGpgCheck._enabledYN.str();
- // GPG Check
- tr << repoGpgCheck._gpgCheckYN.str();
- // autorefresh?
- tr << repoAutorefreshStr( *srv );
-
- // priority
- if ( flags & SF_SHOW_PRIO )
- {
- if ( service )
- tr << "";
- else
- tr << repoPriorityNumber( repo->priority(), 4 );
- }
-
- // type
- if ( service )
- tr << service->type().asString();
- else
- tr << repo->type().asString();
-
- // url
- if ( flags & SF_SHOW_URI )
- {
- if ( service )
- tr << service->url().asString();
- else
- tr << repo->url().asString();
- }
-
- tbl << tr;
-}
-
-// ---------------------------------------------------------------------------
-
-static void print_service_list( Zypper & zypper, const std::list<RepoInfoBase_Ptr> & services )
-{
- Table tbl;
-
- // flags
-
- ServiceListFlags flags( 0 );
- if ( zypper.cOpts().count("details") )
- flags |= SF_SHOW_ALL;
- else
- {
- if ( zypper.cOpts().count("uri")
- || zypper.cOpts().count("url")
- || zypper.cOpts().count("sort-by-uri") )
- flags |= SF_SHOW_URI;
- if ( zypper.cOpts().count("priority")
- || zypper.cOpts().count("sort-by-priority") )
- flags |= SF_SHOW_PRIO;
- }
-
- bool with_repos = zypper.cOpts().count("with-repos");
- //! \todo string type = zypper.cOpts().count("type");
-
- // header
- {
- TableHeader th;
- // fixed 'zypper services' columns
- th << "#"
- << _("Alias")
- << _("Name")
- << _("Enabled")
- << _("GPG Check")
- // translators: 'zypper repos' column - whether autorefresh is enabled for the repository
- << _("Refresh");
- // optional columns
- if ( flags.testFlag( SF_SHOW_PRIO ) )
- // translators: repository priority (in zypper repos -p or -d)
- th << _("Priority");
- th << _("Type");
- if ( flags.testFlag( SF_SHOW_URI ) )
- th << _("URI");
- tbl << std::move(th);
- }
-
- bool show_enabled_only = zypper.cOpts().count("show-enabled-only");
-
- int i = 0;
- for_( it, services.begin(), services.end() )
- {
- ++i; // continuous numbering including skipped ones
-
- bool servicePrinted = false;
- // Unconditionally print the service before the 1st repo is
- // printed. Undesired, but possible, that a disabled service
- // owns (manually) enabled repos.
- if ( with_repos && dynamic_pointer_cast<ServiceInfo>(*it) )
- {
- RepoCollector collector;
- RepoManager & rm( zypper.repoManager() );
-
- rm.getRepositoriesInService( (*it)->alias(),
- make_function_output_iterator( bind( &RepoCollector::collect, &collector, _1 ) ) );
-
- for_( repoit, collector.repos.begin(), collector.repos.end() )
- {
- RepoInfoBase_Ptr ptr( new RepoInfo(*repoit) ); // copy needed?
-
- if ( show_enabled_only && !repoit->enabled() )
- continue;
-
- if ( !servicePrinted )
- {
- service_list_tr( zypper, tbl, *it, i, flags );
- servicePrinted = true;
- }
- // SF_SERVICE_REPO: we print repos of the current service
- service_list_tr( zypper, tbl, ptr, i, flags|SF_SERVICE_REPO );
- }
- }
- if ( servicePrinted )
- continue;
-
- // Here: No repo enforced printing the service, so do so if
- // necessary.
- if ( show_enabled_only && !(*it)->enabled() )
- continue;
-
- service_list_tr( zypper, tbl, *it, i, flags );
- }
-
- if ( tbl.empty() )
- zypper.out().info( str::form(_("No services defined. Use the '%s' command to add one or more services."),
- "zypper addservice" ) );
- else
- {
- // sort
- if ( zypper.cOpts().count("sort-by-uri") )
- {
- if ( flags.testFlag( SF_SHOW_ALL ) )
- tbl.sort( 7 );
- else if ( flags.testFlag( SF_SHOW_PRIO ) )
- tbl.sort( 7 );
- else
- tbl.sort( 6 );
- }
- else if ( zypper.cOpts().count("sort-by-alias") )
- tbl.sort( 1 );
- else if ( zypper.cOpts().count("sort-by-name") )
- tbl.sort( 2 );
- else if ( zypper.cOpts().count("sort-by-priority") )
- tbl.sort( 5 );
-
- // print
- cout << tbl;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-static void print_xml_service_list( Zypper & zypper, const std::list<RepoInfoBase_Ptr> & services )
-{
- cout << "<service-list>" << endl;
-
- ServiceInfo_Ptr s_ptr;
- for_( it, services.begin(), services.end() )
- {
- s_ptr = dynamic_pointer_cast<ServiceInfo>(*it);
- // print also service's repos
- if ( s_ptr )
- {
- RepoCollector collector;
- RepoManager & rm( zypper.repoManager() );
- rm.getRepositoriesInService( (*it)->alias(),
- make_function_output_iterator( bind( &RepoCollector::collect, &collector, _1 ) ) );
- std::ostringstream sout;
- for_( repoit, collector.repos.begin(), collector.repos.end() )
- repoit->dumpAsXmlOn( sout );
- (*it)->dumpAsXmlOn( cout, sout.str() );
- continue;
- }
-
- (*it)->dumpAsXmlOn( cout );
- }
-
- cout << "</service-list>" << endl;
-}
-
-// ---------------------------------------------------------------------------
-
-void list_services( Zypper & zypper )
-{
- ServiceList services = get_all_services( zypper );
-
- // print repo list as xml
- if (zypper.out().type() == Out::TYPE_XML)
- print_xml_service_list( zypper, services );
- else
- print_service_list( zypper, services );
-}
-
-// ---------------------------------------------------------------------------
-
-void add_service( Zypper & zypper, const ServiceInfo & service )
-{
- RepoManager manager( zypper.globalOpts().rm_options );
-
- try
- {
- manager.addService( service );
- }
- catch ( const repo::RepoAlreadyExistsException & e )
- {
- ZYPP_CAUGHT( e );
- ERR << "Service aliased '" << service.alias() << "' already exists." << endl;
- zypper.out().error( str::Format(_("Service aliased '%s' already exists. Please use another alias.")) % service.alias() );
- zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
- return;
- }
- catch ( const Exception & e )
- {
- ZYPP_CAUGHT( e );
- zypper.out().error( str::Format(_("Error occurred while adding service '%s'.")) % service.alias() );
- zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
- return;
- }
-
- MIL << "Service '" << service.alias() << "' has been added." << endl;
- zypper.out().info( str::Format(_("Service '%s' has been successfully added.")) % service.asUserString() );
-}
-
-// ---------------------------------------------------------------------------
-
-void add_service_by_url( Zypper & zypper,
- const Url & url,
- const std::string & alias)
-{
- MIL << "going to add service by url (alias=" << alias << ", url=" << url << ")" << endl;
-
- ServiceInfo service;
-
- service.setAlias( alias.empty() ? timestamp() : alias );
- parsed_opts::const_iterator it = zypper.cOpts().find("name");
- if ( it != zypper.cOpts().end() )
- service.setName( it->second.front() );
- service.setUrl( url );
-
- TriBool bopt = get_boolean_option( zypper, "enable", "disable" );
- service.setEnabled( indeterminate(bopt) ? true : bool(bopt) );
-
- bopt = get_boolean_option( zypper, "refresh", "no-refresh" );
- service.setAutorefresh( indeterminate(bopt) ? true : bool(bopt) );
-
- add_service( zypper, service );
-}
-
-
-// ---------------------------------------------------------------------------
-
-void remove_service( Zypper & zypper, const ServiceInfo & service )
-{
- RepoManager & manager( zypper.repoManager() );
-
- zypper.out().info( str::Format(_("Removing service '%s':")) % service.asUserString() );
- manager.removeService( service );
- MIL << "Service '" << service.alias() << "' has been removed." << endl;
- zypper.out().info( str::Format(_("Service '%s' has been removed.")) % service.asUserString() );
-}
-
-// ---------------------------------------------------------------------------
-
-static bool refresh_service( Zypper & zypper, const ServiceInfo & service )
-{
- MIL << "going to refresh service '" << service.alias() << "'" << endl;
- init_target( zypper ); // need targetDistribution for service refresh
- RepoManager & manager( zypper.repoManager() );
-
- bool error = true;
- try
- {
- zypper.out().info( str::form(_("Refreshing service '%s'."), service.asUserString().c_str() ) );
-
- RepoManager::RefreshServiceOptions opts;
- if ( zypper.cOpts().count("restore-status") )
- opts |= RepoManager::RefreshService_restoreStatus;
- if ( zypper.cOpts().count("force")
- && ( zypper.command() == ZypperCommand::REFRESH || zypper.command() == ZypperCommand::REFRESH_SERVICES ) )
- opts |= RepoManager::RefreshService_forceRefresh;
-
- manager.refreshService( service, opts );
- error = false;
- }
- catch ( const repo::ServicePluginInformalException & e )
- {
- ZYPP_CAUGHT( e );
- zypper.out().error( e, str::form(_("Problem retrieving the repository index file for service '%s':"),
- service.asUserString().c_str()));
- zypper.out().warning( str::form( _("Skipping service '%s' because of the above error."),
- service.asUserString().c_str()));
- // this is just an informal note. The service will be used as is (usually empty)
- error = false;
- }
- catch ( const media::MediaException & e )
- {
- ZYPP_CAUGHT( e );
- zypper.out().error( e, str::form(_("Problem retrieving the repository index file for service '%s':"),
- service.asUserString().c_str() ),
- _("Check if the URI is valid and accessible.") );
- zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
- }
-
- return error;
-}
-
-// ---------------------------------------------------------------------------
-
-void refresh_services( Zypper & zypper )
-{
- MIL << "going to refresh services" << endl;
-
- ServiceList services = get_all_services( zypper );
-
- // get the list of repos specified on the command line ...
- ServiceList specified;
- std::list<std::string> not_found;
- // ...as command arguments
- get_services( zypper, zypper.arguments().begin(), zypper.arguments().end(), specified, not_found );
- report_unknown_services( zypper.out(), not_found ) ;
-
- unsigned error_count = 0;
- unsigned enabled_service_count = services.size();
-
- if ( !specified.empty() || not_found.empty() )
- {
- unsigned number = 0;
- for_( sit, services.begin(), services.end() )
- {
- ++number;
- RepoInfoBase_Ptr service_ptr( *sit );
-
- // skip services not specified on the command line
- if ( !specified.empty() )
- {
- bool found = false;
- for_( it, specified.begin(), specified.end() )
- if ( (*it)->alias() == service_ptr->alias() )
- {
- found = true;
- break;
- }
-
- if ( !found )
- {
- DBG << service_ptr->alias() << "(#" << number << ") not specified," << " skipping." << endl;
- --enabled_service_count;
- continue;
- }
- }
-
- // skip disabled services
- if ( !service_ptr->enabled() )
- {
- DBG << "skipping disabled service '" << service_ptr->alias() << "'" << endl;
-
- std::string msg = str::Format(_("Skipping disabled service '%s'")) % service_ptr->asUserString();
- if ( specified.empty() )
- zypper.out().info( msg, Out::HIGH );
- else
- zypper.out().error( msg );
-
- --enabled_service_count;
- continue;
- }
-
- // do the refresh
- bool error = false;
- ServiceInfo_Ptr s = dynamic_pointer_cast<ServiceInfo>(service_ptr);
- if ( s )
- {
- error = refresh_service( zypper, *s );
-
- // refresh also service's repos
- if ( zypper.cOpts().count("with-repos") )
- {
- RepoCollector collector;
- RepoManager & rm = zypper.repoManager();
- rm.getRepositoriesInService( s->alias(),
- make_function_output_iterator( bind( &RepoCollector::collect, &collector, _1 ) ) );
- for_( repoit, collector.repos.begin(), collector.repos.end() )
- refresh_repo( zypper, *repoit );
- }
- }
- else
- {
- if ( !zypper.cOpts().count("with-repos") )
- {
- DBG << "Skipping non-index service '" << service_ptr->asUserString() << "' because '--no-repos' is used.";
- continue;
- }
- error = refresh_repo( zypper, *dynamic_pointer_cast<RepoInfo>(service_ptr) );
- }
-
- if ( error )
- {
- ERR << "Skipping service '" << service_ptr->alias() << "' because of the above error." << endl;
- zypper.out().error( str::Format(_("Skipping service '%s' because of the above error.")) % service_ptr->asUserString().c_str() );
- ++error_count;
- }
- }
- }
- else
- enabled_service_count = 0;
-
- // print the result message
- if ( enabled_service_count == 0 )
- {
- std::string hint = str::form(_("Use '%s' or '%s' commands to add or enable services."),
- "zypper addservice", "zypper modifyservice" );
- if ( !specified.empty() || !not_found.empty() )
- zypper.out().error(_("Specified services are not enabled or defined."), hint);
- else
- zypper.out().error(_("There are no enabled services defined."), hint);
- }
- else if ( error_count == enabled_service_count )
- {
- zypper.out().error(_("Could not refresh the services because of errors.") );
- zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
- return;
- }
- else if ( error_count )
- {
- zypper.out().error(_("Some of the services have not been refreshed because of an error.") );
- zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
- return;
- }
- else if ( !specified.empty() )
- zypper.out().info(_("Specified services have been refreshed.") );
- else
- zypper.out().info(_("All services have been refreshed.") );
-
- MIL << "DONE";
-}
-
-void checkIfToRefreshPluginServices( Zypper & zypper )
+void checkIfToRefreshPluginServices(Zypper & zypper, RepoManager::RefreshServiceFlags flags_r)
{
// check root user
if ( geteuid() != 0 )
if ( ! service.autorefresh() )
continue;
- bool error = refresh_service( zypper, service );
+ bool error = refresh_service( zypper, service, flags_r );
if (error)
{
ERR << "Skipping service '" << service.alias() << "' because of the above error." << endl;
}
}
-
-// ---------------------------------------------------------------------------
-
-void modify_service( Zypper & zypper, const std::string & alias )
-{
- // enable/disable repo
- TriBool enable = get_boolean_option( zypper,"enable", "disable" );
- DBG << "enable = " << enable << endl;
-
- // autorefresh
- TriBool autoref = get_boolean_option( zypper,"refresh", "no-refresh" );
- DBG << "autoref = " << autoref << endl;
-
- try
- {
- RepoManager & manager = zypper.repoManager();
- ServiceInfo srv( manager.getService( alias ) );
-
- bool changed_enabled = false;
- bool changed_autoref = false;
-
- if ( !indeterminate(enable) )
- {
- if ( enable != srv.enabled() )
- changed_enabled = true;
- srv.setEnabled( enable );
- }
-
- if ( !indeterminate(autoref) )
- {
- if ( autoref != srv.autorefresh() )
- changed_autoref = true;
- srv.setAutorefresh( autoref );
- }
-
- std::string name;
- parsed_opts::const_iterator tmp1;
- if ( (tmp1 = zypper.cOpts().find("name")) != zypper.cOpts().end() )
- {
- name = *tmp1->second.begin();
- srv.setName( name );
- }
-
- std::set<std::string> artoenable;
- std::set<std::string> artodisable;
- std::set<std::string> rrtoenable;
- std::set<std::string> rrtodisable;
-
- // RIS repos to enable
- if ( zypper.cOpts().count("cl-to-enable") )
- {
- rrtoenable.insert( srv.reposToEnableBegin(), srv.reposToEnableEnd() );
- srv.clearReposToEnable();
- }
- else
- {
- if ( (tmp1 = zypper.cOpts().find("ar-to-enable")) != zypper.cOpts().end() )
- for_( rit, tmp1->second.begin(), tmp1->second.end() )
- {
- if ( !srv.repoToEnableFind( *rit ) )
- {
- srv.addRepoToEnable( *rit );
- artoenable.insert( *rit );
- }
- }
- if ( (tmp1 = zypper.cOpts().find("rr-to-enable")) != zypper.cOpts().end() )
- for_( rit, tmp1->second.begin(), tmp1->second.end() )
- {
- if ( srv.repoToEnableFind( *rit ) )
- {
- srv.delRepoToEnable( *rit );
- rrtoenable.insert( *rit );
- }
- }
- }
-
- // RIS repos to disable
- if ( zypper.cOpts().count("cl-to-disable") )
- {
- rrtodisable.insert( srv.reposToDisableBegin(), srv.reposToDisableEnd() );
- srv.clearReposToDisable();
- }
- else
- {
- if ( (tmp1 = zypper.cOpts().find("ar-to-disable")) != zypper.cOpts().end() )
- for_( rit, tmp1->second.begin(), tmp1->second.end() )
- {
- if ( !srv.repoToDisableFind( *rit ) )
- {
- srv.addRepoToDisable( *rit );
- artodisable.insert( *rit );
- }
- }
- if ( (tmp1 = zypper.cOpts().find("rr-to-disable")) != zypper.cOpts().end() )
- for_( rit, tmp1->second.begin(), tmp1->second.end() )
- {
- if (srv.repoToDisableFind( *rit ) )
- {
- srv.delRepoToDisable( *rit );
- rrtodisable.insert( *rit );
- }
- }
- }
-
- if ( changed_enabled
- || changed_autoref
- || !name.empty()
- || !artoenable.empty()
- || !artodisable.empty()
- || !rrtoenable.empty()
- || !rrtodisable.empty() )
- {
- manager.modifyService( alias, srv );
-
- if ( changed_enabled )
- {
- if ( srv.enabled() )
- zypper.out().info( str::Format(_("Service '%s' has been successfully enabled.")) % alias );
- else
- zypper.out().info( str::Format(_("Service '%s' has been successfully disabled.")) % alias );
- }
-
- if ( changed_autoref )
- {
- if ( srv.autorefresh() )
- zypper.out().info( str::Format(_("Autorefresh has been enabled for service '%s'.")) % alias );
- else
- zypper.out().info( str::Format(_("Autorefresh has been disabled for service '%s'.")) % alias );
- }
-
- if ( !name.empty() )
- {
- zypper.out().info( str::Format(_("Name of service '%s' has been set to '%s'.")) % alias % name );
- }
-
- if ( !artoenable.empty() )
- {
- zypper.out().info( str::Format(PL_("Repository '%s' has been added to enabled repositories of service '%s'",
- "Repositories '%s' have been added to enabled repositories of service '%s'",
- artoenable.size()))
- % str::join( artoenable.begin(), artoenable.end(), ", " ) % alias );
- }
- if ( !artodisable.empty() )
- {
- zypper.out().info( str::Format(PL_("Repository '%s' has been added to disabled repositories of service '%s'",
- "Repositories '%s' have been added to disabled repositories of service '%s'",
- artodisable.size()))
- % str::join( artodisable.begin(), artodisable.end(), ", " ) % alias );
- }
- if ( !rrtoenable.empty() )
- {
- zypper.out().info( str::Format(PL_("Repository '%s' has been removed from enabled repositories of service '%s'",
- "Repositories '%s' have been removed from enabled repositories of service '%s'",
- rrtoenable.size()))
- % str::join( rrtoenable.begin(), rrtoenable.end(), ", " ) % alias );
- }
- if ( !rrtodisable.empty())
- {
- zypper.out().info( str::Format(PL_("Repository '%s' has been removed from disabled repositories of service '%s'",
- "Repositories '%s' have been removed from disabled repositories of service '%s'",
- rrtodisable.size()))
- % str::join( rrtodisable.begin(), rrtodisable.end(), ", " ) % alias );
- }
- }
- else
- {
- MIL << "Nothing to modify in '" << alias << "':" << srv << endl;
- zypper.out().info( str::Format(_("Nothing to change for service '%s'.")) % alias );
- }
- }
- catch ( const Exception & ex )
- {
- ERR << "Error while modifying the service:" << ex.asUserString() << endl;
- zypper.out().error( ex, _("Error while modifying the service:"),
- str::Format(_("Leaving service %s unchanged.")) % alias );
- zypper.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
- }
-}
-
// ---------------------------------------------------------------------------
-void modify_services_by_option( Zypper & zypper )
-{
- ServiceList known = get_all_services( zypper );
- std::set<std::string> repos_to_modify;
- std::set<std::string> services_to_modify;
-
- if ( copts.count("all") )
- {
- for_( it, known.begin(), known.end() )
- {
- ServiceInfo_Ptr sptr = dynamic_pointer_cast<ServiceInfo>(*it);
- if ( sptr )
- modify_service( zypper, sptr->alias() );
- else
- modify_repo( zypper, (*it)->alias() );
- }
- return;
- }
-
- bool local = copts.count("local");
- bool remote = copts.count("remote");
- std::list<std::string> pars = copts["medium-type"];
- std::set<std::string> schemes(pars.begin(), pars.end());
-
- for_( it, known.begin(), known.end() )
- {
- ServiceInfo_Ptr sptr = dynamic_pointer_cast<ServiceInfo>(*it);
- Url url;
- if ( sptr )
- url = sptr->url();
- else
- {
- RepoInfo_Ptr rptr = dynamic_pointer_cast<RepoInfo>(*it);
- if ( !rptr->baseUrlsEmpty() )
- url = rptr->url();
- }
-
- if ( url.isValid() )
- {
- bool modify = false;
- if ( local && ! url.schemeIsDownloading() )
- modify = true;
-
- if ( !modify && remote && url.schemeIsDownloading() )
- modify = true;
-
- if ( !modify && schemes.find(url.getScheme()) != schemes.end() )
- modify = true;
-
- if ( modify )
- {
- std::string alias = (*it)->alias();
- if ( sptr )
- services_to_modify.insert( alias );
- else
- repos_to_modify.insert( alias );
- }
- }
- else
- WAR << "got invalid url: " << url.asString() << endl;
- }
-
- for_( it, services_to_modify.begin(), services_to_modify.end() )
- modify_service( zypper, *it );
-
- for_( it, repos_to_modify.begin(), repos_to_modify.end() )
- modify_repo( zypper, *it );
-}
-
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <list>
+#include <boost/lexical_cast.hpp>
+
#include <zypp/TriBool.h>
#include <zypp/Url.h>
#include <zypp/RepoInfo.h>
#include <zypp/ServiceInfo.h>
#include "Zypper.h"
+#include "commands/reposerviceoptionsets.h"
#define TMP_RPM_REPO_ALIAS "_tmpRPMcache_"
+// | Enabled | GPG Check | Colored strings for enabled and GPG Check status
+// +---------+-----------+
+// | Yes | ( ) No |
+// | Yes | (rp) Yes |
+// | No | ---- |
+struct RepoGpgCheckStrings
+{
+ RepoGpgCheckStrings();
+
+ RepoGpgCheckStrings( const ServiceInfo & service_r );
+ RepoGpgCheckStrings( const RepoInfo & repo_r );
+
+ ColorContext _tagColor; ///< color according to enabled and GPG Check status
+ ColorString _enabledYN; ///< colored enabled Yes/No
+ ColorString _gpgCheckYN; ///< colored GPG Check status if enabled else "----"
+};
+
+inline std::string timestamp()
+{ return Date::now().form("%Y%m%d-%H%M%S"); }
+
/**
* The same as \ref init_repos(), but allows to specify repos to initialize.
*
template <typename Container>
void init_repos( Zypper & zypper, const Container & container = Container() );
+/**
+ * Say "Repository %s not found" for all strings in \a not_found list.
+ */
+void report_unknown_repos( Out & out, const std::list<std::string> & not_found );
+
template<typename T>
void get_repos( Zypper & zypper, const T & begin, const T & end, std::list<RepoInfo> & repos, std::list<std::string> & not_found );
+template <typename Target, typename Source>
+void safe_lexical_cast( Source s, Target & tr )
+{
+ try
+ {
+ tr = boost::lexical_cast<Target>( s );
+ }
+ catch ( boost::bad_lexical_cast & )
+ {;}
+}
+
void report_unknown_repos( Out & out, const std::list<std::string> & not_found );
/**
void list_repos( Zypper & zypper );
/**
- * Refresh all enabled repositories.
- */
-void refresh_repos( Zypper & zypper );
-
-/**
- * Refresh a single repository.
- * \return true on error, false otherwise
- */
-bool refresh_repo( Zypper & zypper, const RepoInfo & repo );
-
-
-/**
* Clean caches for all (specified) repositories.
*/
-void clean_repos( Zypper & zypper );
+enum class CleanRepoBits {
+ Default = 0,
+ CleanMetaData = 1,
+ CleanRawMetaData = 2,
+ CleanAll = CleanMetaData | CleanRawMetaData
+};
+ZYPP_DECLARE_FLAGS_AND_OPERATORS(CleanRepoFlags, CleanRepoBits)
+void clean_repos(Zypper & zypper, std::vector<std::string> specificRepos, CleanRepoFlags flags );
/**
* Try match given string with any known repository.
*
* \param str string to match
* \param repo pointer to fill with found repository
+ * \param looseQuery_r Ignore query string in the URI if true.
+ * \param looseAuth_r Ignore user authentication data in the URI if true.
* \return success if respository is found
*/
-bool match_repo( Zypper & zypper, const std::string str, RepoInfo *repo = 0 );
-
+bool match_repo( Zypper & zypper, const std::string str, RepoInfo *repo = 0 , bool looseQuery_r = false, bool looseAuth_r = false );
/**
* Add repository specified by \url to system repositories.
*/
void add_repo_by_url(Zypper & zypper,
const Url & url,
- const std::string & alias);
+ const std::string & alias,
+ const RepoServiceCommonOptions &opts,
+ const RepoProperties &repoProps, bool noCheck);
/**
* Add repository specified in given repo file on \a repo_file_url. All repos
* \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,
- const std::string & repo_file_url );
+void add_repo_from_file(Zypper & zypper,
+ const std::string & repo_file_url , const RepoServiceCommonOptions &opts, const RepoProperties &repoProps, bool noCheck);
/**
* Add repository specified by \repo to system repositories.
*/
-bool add_repo( Zypper & zypper, RepoInfo & repo );
+bool add_repo(Zypper & zypper, RepoInfo & repo , bool noCheck);
+
/**
* Remove repository specified by \a alias.
* Remove repositories which is matching filter options
* like all, local, remote or medium-type
*/
-void remove_repos_by_option( Zypper & zypper );
-
-/**
- * Rename repository specified by \a alias to \a newalias.
- */
-void rename_repo( Zypper & zypper, const std::string & alias, const std::string & newalias );
+void remove_repos_by_option(Zypper & zypper_r , const RepoServiceCommonSelectOptions selOpts_r);
/**
* 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_repo( Zypper & zypper, const std::string & alias, const RepoServiceCommonOptions &commonOpts, const RepoProperties &repoProps );
/**
* Modify repositories which is matching filter options
* like all, local, remote or medium-type
*/
-void modify_repos_by_option( Zypper & zypper );
-
-
-void list_services( Zypper & zypper );
-
-void add_service( Zypper & zypper, const ServiceInfo & service );
-
-void add_service_by_url(Zypper & zypper,
- const Url & url,
- const std::string & alias);
+void modify_repos_by_option( Zypper & zypper, const RepoServiceCommonSelectOptions &selectOpts, const RepoServiceCommonOptions &commonOpts, const RepoProperties &repoProps );
void remove_service( Zypper & zypper, const ServiceInfo & service );
void modify_service( Zypper & zypper, const std::string & alias );
-void refresh_services( Zypper & zypper );
-
/** If root, refresh any plugin services before lr/ls/ref (bnc#893294) */
-void checkIfToRefreshPluginServices( Zypper & zypper );
-
-bool match_service( Zypper & zypper, std::string str, repo::RepoInfoBase_Ptr & service_ptr );
+void checkIfToRefreshPluginServices( Zypper & zypper, RepoManager::RefreshServiceFlags flags_r = RepoManager::RefreshServiceFlags() );
void modify_services_by_option( Zypper & zypper );
*/
void load_repo_resolvables( Zypper & zypper );
+ColorString repoPriorityNumber( unsigned prio_r, int width_r = 0 );
+ColorString repoPriorityNumberAnnotated( unsigned prio_r, int width_r = 0 );
+
+const char * repoAutorefreshStr( const repo::RepoInfoBase & repo_r );
+
+/** \return true if aliases are equal, and all lhs urls can be found in rhs */
+bool repo_cmp_alias_urls( const RepoInfo & lhs, const RepoInfo & rhs );
+
+/**
+ * @TODO remove me with copts
+ */
+unsigned priority_from_copts( Zypper &zypper );
+
+void repoPrioSummary( Zypper & zypper );
+
+bool refresh_raw_metadata( Zypper & zypper, const RepoInfo & repo, bool force_download );
+
+bool build_cache( Zypper & zypper, const RepoInfo & repo, bool force_build );
+
#endif
// Local Variables:
// mode: c++
// scan installed packages to manifest
{
- if ( _zypper.defaultLoadSystem( _options->_dryrun ? NO_REPOS : LoadSystemFlags() ) != ZYPPER_EXIT_OK )
+ if ( _zypper.defaultLoadSystem( _options->_dryrun ? NoRepos : LoadSystemFlags() ) != ZYPPER_EXIT_OK )
{
ERR << "Startup returns " << _zypper.exitCode() << endl;
throw( Out::Error(_("Failed to read download directory"),
}
InvalidValueException::InvalidValueException(const std::string &flag, const std::string &invalidValue, const std::string &reason)
- : ZyppFlagsException( str::Format(_("The flag %1% is not compatible with argument %2% (%2).")) % flag % invalidValue % reason )
+ : ZyppFlagsException( str::Format(_("The flag %1% is not compatible with argument %2% (%3%).")) % flag % invalidValue % reason )
{
}
}
+ConflictingFlagsException::ConflictingFlagsException(const std::string &flag, const std::string &flag2)
+ : ZyppFlagsException( str::Format( _("%s used together with %s, which contradict each other.") ) % flag % flag2 )
+{
+
+}
+
}}
public:
FlagRepeatedException ( const std::string &flag );
};
+
+ class ConflictingFlagsException : public ZyppFlagsException
+ {
+ public:
+ ConflictingFlagsException ( const std::string &flag, const std::string &flag2 );
+ };
}}
\*---------------------------------------------------------------------------*/
#include "flagtypes.h"
#include "main.h"
+#include "utils/messages.h"
+#include "utils/misc.h"
namespace zypp {
namespace ZyppFlags {
+namespace {
+
+ResKind parseKindArgument( const CommandOption &opt, const boost::optional<std::string> &in)
+{
+ if (!in) ZYPP_THROW(MissingArgumentException(opt.name)); //value required
+ ResKind knd = string_to_kind(*in);
+ if ( knd == ResKind::nokind )
+ ZYPP_THROW(InvalidValueException( opt.name, *in, _("Unknown package type")));
+
+ return knd;
+}
+
+}
+
+boost::optional<std::string> noDefaultValue()
+{
+ return boost::optional<std::string>();
+}
+
Value StringType(std::string *target, const boost::optional<const char *> &defValue, std::string hint) {
return Value (
[defValue]() -> boost::optional<std::string>{
);
}
+Value TriBoolType(TriBool &target, StoreFlag store, const boost::optional<TriBool> &defValue)
+{
+ return Value (
+ [defValue]() -> boost::optional<std::string>{
+ if (!defValue)
+ return boost::optional<std::string>();
+ return asString ( *defValue );
+ },
+ [&target, store]( const CommandOption &, const boost::optional<std::string> &){
+ target = TriBool(store == StoreTrue);
+ }
+ );
+}
+
+Value CounterType(int *target, const boost::optional<int> &defValue, const boost::optional<int> &maxValue)
+{
+ return Value (
+ [defValue]() -> boost::optional<std::string>{
+ if(defValue) {
+ return std::to_string(*defValue);
+ } else
+ return boost::optional<std::string>();
+ },
+
+ [target, maxValue]( const CommandOption &opt, const boost::optional<std::string> & ) {
+ *target += 1;
+ if ( maxValue && *target > *maxValue)
+ ZYPP_THROW(ZyppFlagsException(str::Format(_("The flag '%1%' can only be used a maximum of %2% times.")) % opt.name % *maxValue));
+ }
+ );
+}
+
+
+Value KindSetType(std::set<ResKind> *target) {
+ return Value (
+ noDefaultValue,
+ [target] ( const CommandOption &opt, const boost::optional<std::string> &in ) {
+ target->insert( parseKindArgument( opt, in ) );
+ return;
+ },
+ "TYPE"
+ );
+}
+
+Value StringVectorType(std::vector<std::string> *target, std::string hint) {
+ return Value (
+ noDefaultValue,
+ [target] ( const CommandOption &opt, const boost::optional<std::string> &in ) {
+ if ( !in || in->empty() ) ZYPP_THROW(MissingArgumentException(opt.name)); //value required
+ target->push_back(*in);
+ return;
+ },
+ std::move(hint)
+ );
+}
+
+Value NoValue()
+{
+ return Value (
+ noDefaultValue,
+ []( const CommandOption &, const boost::optional<std::string> & ) {
+ return;
+ }
+ );
+}
+
+Value WarnOptionVal(Out &out_r, const std::string &warning_r, Out::Verbosity verbosity_r, const boost::optional<Value> &val_r )
+{
+ return Value (
+ [ val_r ] () -> boost::optional<std::string> {
+ if ( val_r )
+ return val_r->defaultValue();
+ return boost::optional<std::string>();
+ },
+ [ &out_r, warning_r, val_r, verbosity_r ] ( const CommandOption &opt, const boost::optional<std::string> &in ) {
+ out_r.warning( warning_r, verbosity_r );
+ if ( val_r ) {
+ Value val = *val_r; // C++ forces us to copy by value again
+ val.set ( opt, in );
+ }
+ }
+ );
+}
+
}
}
#include "zyppflags.h"
#include "exceptions.h"
+#include "output/Out.h"
+
+#include <zypp/ResKind.h>
+#include <zypp/TriBool.h>
+#include <set>
+
+class Out;
namespace zypp {
+
+class Kind;
+
namespace ZyppFlags {
/**
*/
Value IntType ( int *target, const boost::optional<int> &defValue = boost::optional<int>() );
+/**
+ * Returns a \sa ZyppFlags::Value instance counting how many times a parameter was seen
+ */
+Value CounterType ( int *target, const boost::optional<int> &defValue = boost::optional<int>(), const boost::optional<int> &maxValue = boost::optional<int>() );
-template <class Container>
-Value StringContainerType ( Container *target, std::string hint = ARG_STRING ) {
- return Value (
- []() -> boost::optional<std::string> { return boost::optional<std::string>(); },
- [target] ( CommandOption *opt, const boost::optional<std::string> &in ) {
- if (!in) ZYPP_THROW(MissingArgumentException(opt->name)); //value required
- target->push_back(*in);
- return;
- },
- std::move(hint)
- );
-}
+/**
+ * Returns a \sa ZyppFlags::Value instance handling flags taking package or ressource types
+ */
+Value KindSetType ( std::set<ResKind> *target );
+/**
+ * Returns a \sa ZyppFlags::Value instance handling flags that fill a vector of strings
+ */
+Value StringVectorType (std::vector<std::string> *target, std::string hint = "STRING" );
/**
* Specifies how to handle when a boolean flag was seen on commandline
*/
Value BoolType ( bool *target, StoreFlag store = StoreTrue, const boost::optional<bool> &defValue = boost::optional<bool>() );
+
+Value TriBoolType ( TriBool &target, StoreFlag store = StoreTrue, const boost::optional<TriBool> &defValue = boost::optional<TriBool>() );
+
+
+template <typename T, typename E = T>
+Value BitFieldType ( T& target, E flag , StoreFlag store = StoreTrue ) {
+ return Value (
+ [ &target, flag] () -> boost::optional<std::string> {
+ return target.testFlag ( flag ) ? std::string("true") : std::string("false");
+ },
+ [ &target, flag, store ] ( const CommandOption &, const boost::optional<std::string> & ) {
+ if ( store == StoreTrue )
+ target.setFlag ( flag );
+ else
+ target.unsetFlag ( flag );
+ }
+ );
+}
+
+/**
+ * Creates a null type, calling the setter or default value getter for this type will do nothing.
+ * Use this to have a ignored deprecated flag
+ */
+Value NoValue ();
+
+/**
+ * Creates a value that emits a warning when set, if \a val_r is valid the calls are forwarded to it after
+ * emitting the warning.
+ */
+Value WarnOptionVal (Out &out_r , const std::string &warning_r, Out::Verbosity verbosity_r = Out::NORMAL, const boost::optional<Value> &val_r = boost::optional<Value>());
+
+/**
+ * Helper function that just returns a empty default value
+ */
+boost::optional<std::string> noDefaultValue();
+
}}
#endif
|__/|_| |_|
\*---------------------------------------------------------------------------*/
#include "zyppflags.h"
+#include "flagtypes.h"
+#include "exceptions.h"
+#include "utils/messages.h"
+#include "Zypper.h"
#include <getopt.h>
-#include <map>
+#include <unordered_map>
#include <exception>
#include <utility>
#include <string.h>
-#include "exceptions.h"
-
namespace zypp
{
case OptionalArgument:
has_arg = optional_argument;
break;
+ default:
+ throw ZyppFlagsException( str::Format("Invalid opt.flags value for option: %1%") % opt.name );
}
//we do not use the flag and val types, instead we use optind to figure out what happend
return _argHint;
}
+bool Value::wasSet() const
+{
+ return _wasSet;
+}
+
int parseCLI(const int argc, char * const *argv, const std::vector<CommandGroup> &options, const int firstOpt)
{
// the short options string as used int getopt
// the set of long options
std::vector<struct option> longopts;
+ // the set of all conflicting options
+ ConflictingFlagsList conflictingFlags;
+
//build a complete list and a long and short option index so we can
//easily get to the CommandOption
std::vector<CommandOption> allOpts;
- std::map<std::string, int> longOptIndex; //we do not actually need that index other than checking for dups
- std::map<char, int> shortOptIndex;
+ std::unordered_map<std::string, int> longOptIndex; //we do not actually need that index other than checking for dups
+ std::unordered_map<char, int> shortOptIndex;
for ( const CommandGroup &grp : options ) {
for ( const CommandOption &currOpt : grp.options ) {
allOpts.push_back( currOpt );
int allOptIndex = allOpts.size() - 1;
+ int flags = currOpt.flags;
- if ( currOpt.flags & RequiredArgument && currOpt.flags & OptionalArgument ) {
+ if ( flags & RequiredArgument && flags & OptionalArgument ) {
throw ZyppFlagsException("Argument can either be Required or Optional");
}
if ( !currOpt.name.empty() ) {
if ( !longOptIndex.insert( { currOpt.name, allOptIndex } ).second) {
- throw ZyppFlagsException("Duplicate long option <insertnamehere>");
+ throw ZyppFlagsException( str::Format("Duplicate long option ''%1%") % currOpt.name );
}
appendToLongOptions( currOpt, longopts );
}
if ( currOpt.shortName ) {
if ( !shortOptIndex.insert( { currOpt.shortName, allOptIndex } ).second) {
- throw ZyppFlagsException("Duplicate short option <insertnamehere>");
+ throw ZyppFlagsException( str::Format("Duplicate short option %1%") % currOpt.shortName );
}
appendToOptString( currOpt, shortopts );
}
- allOptIndex++;
+
+ conflictingFlags.insert( conflictingFlags.end(), grp.conflictingOptions.begin(), grp.conflictingOptions.end() );
}
}
if ( option_index == -1 && optopt)
ZYPP_THROW(UnknownFlagException( std::string(1, optopt)) );
else
- ZYPP_THROW(argv[optind - 1]);
+ ZYPP_THROW(UnknownFlagException( std::string(argv[optind - 1]) ) );
break;
}
case ':': {
arg = std::string(optarg);
}
- allOpts[index].value.set( allOpts[index], arg);
- }
+ CommandOption &opt = allOpts[index];
+ // check if a conflicting option was used before
+ std::vector<std::string> conflictingList;
+ for ( const auto &flagSet : conflictingFlags ) {
+ if ( std::find( flagSet.begin(), flagSet.end(), opt.name ) != flagSet.end() ) {
+ std::copy_if( flagSet.begin(), flagSet.end(), std::back_inserter(conflictingList), [ &opt ]( const std::string &val ) {
+ return val != opt.name;
+ });
+ }
+ }
+
+ if ( !conflictingList.empty() ) {
+ for ( const std::string conflicting : conflictingList ){
+ auto it = longOptIndex.find( conflicting );
+ if ( it == longOptIndex.end() ) {
+ WAR << "Ignoring unknown option " << conflicting << " specified as conflicting flag for " << opt.name << endl;
+ } else {
+ if ( allOpts[it->second].value.wasSet() ) {
+ throw ConflictingFlagsException( opt.name, conflicting );
+ }
+ }
+ }
+ }
+ opt.value.set( allOpts[index], arg );
+ }
break;
}
}
}
}
+CommandOption::CommandOption( std::string &&name_r, char shortName_r, int flags_r, Value &&value_r, std::string &&help_r )
+ : name ( std::move(name_r) ),
+ shortName ( shortName_r ),
+ flags ( flags_r ),
+ value ( std::move(value_r) ),
+ help ( std::move(help_r) )
+{ }
+
+CommandGroup::CommandGroup(std::string &&name_r, std::vector<CommandOption> &&options_r, ConflictingFlagsList &&conflictingOptions_r )
+ : name ( std::move(name_r) ),
+ options ( std::move(options_r) ),
+ conflictingOptions ( std::move(conflictingOptions_r) )
+{ }
+
+CommandGroup::CommandGroup( std::vector<CommandOption> &&options_r, ConflictingFlagsList &&conflictingOptions_r )
+ : CommandGroup ( _("Command options:"), std::move(options_r), std::move(conflictingOptions_r) )
+{ }
+
+CommandGroup::CommandGroup()
+ : CommandGroup ( std::vector<CommandOption>(), ConflictingFlagsList() )
+{ }
+
+
}}
using SetterFun = std::function<void ( const CommandOption &, const boost::optional<std::string> &in)>;
enum ArgFlags : int {
- NoArgument = 0x00,
- RequiredArgument = 0x01,
- OptionalArgument = 0x02,
- ArgumentTypeMask = 0x0F,
-
- Repeatable = 0x10, // < the argument can be repeated
- Hidden = 0x20 // < command is hidden in help
+ NoArgument = 0x00,
+ RequiredArgument = 0x01,
+ OptionalArgument = 0x02,
+ ArgumentTypeMask = 0x0F,
+
+ Repeatable = 0x10, // < the argument can be repeated
+ Hidden = 0x20, // < command is hidden in help
+ Deprecated = 0x40 // < the option is about to be removed in the future
};
/**
*/
std::string argHint () const;
+
+ bool wasSet () const;
+
private:
bool _wasSet = false;
DefValueFun _defaultVal;
struct CommandOption
{
+ CommandOption ( std::string &&name_r, char shortName_r, int flags_r, Value &&value_r, std::string &&help_r = std::string());
+
std::string name;
char shortName;
int flags;
Value value;
std::string help;
+ std::vector<std::string> conflictingArguments;
};
- struct CommandGroup
+ using ConflictingFlagsList = std::vector< std::vector< std::string > >;
+
+ struct CommandGroup
{
- const std::string name;
- std::vector<CommandOption> options;
+ /**
+ * Creates a empty default group
+ */
+ CommandGroup ();
+
+ /**
+ * Creates the default command group with given options and conflicting flags
+ */
+ CommandGroup ( std::vector<CommandOption> &&options_r, ConflictingFlagsList &&conflictingOptions_r = ConflictingFlagsList() );
+
+ /**
+ * Creates the command group with given options, conflicting flags and the custom \a name_r
+ */
+ CommandGroup ( std::string &&name_r, std::vector<CommandOption> &&options_r, ConflictingFlagsList &&conflictingOptions_r = ConflictingFlagsList() );
+
+ std::string name; //< The name of the command group
+ std::vector<CommandOption> options; //< The flags the command group supports
+ ConflictingFlagsList conflictingOptions; //< A list of conflicting flag pairs, each element specifies two flags that can't be used together
};
/**
// ----------------------------------------------------------------------------
+void report_too_few_arguments( const std::string & specific_help )
+{
+ report_too_few_arguments( Zypper::instance().out(), specific_help );
+}
+
+void report_too_few_arguments( Out & out, const std::string & specific_help )
+{
+ //! \todo make this more explanatory, e.g. "Ingoring arg1 arg2. This command does not take arguments. See %s for more information."
+ std::ostringstream s;
+ s << _("Usage") << ':' << endl << specific_help;
+ out.error(_("Too few arguments."), s.str() );
+}
+
+// ----------------------------------------------------------------------------
+
void report_alias_or_aggregate_required ( Out & out, const std::string & specific_help )
{
// translators: aggregate option is e.g. "--all". This message will be
" It is recommended to run '%s' after the operation has finished."),
"zypper verify"));
}
+
+std::string legacyCLIStr( const std::string & old_r, const std::string & new_r, LegacyCLIMsgType type_r )
+{
+ switch (type_r) {
+ case LegacyCLIMsgType::Local:
+ case LegacyCLIMsgType::Global:
+ return str::Format( type_r == LegacyCLIMsgType::Global
+ ? _("Legacy commandline option %1% detected. Please use global option %2% instead.")
+ : _("Legacy commandline option %1% detected. Please use %2% instead.") )
+ % NEGATIVEString(dashdash(old_r))
+ % POSITIVEString(dashdash(new_r));
+ break;
+ case LegacyCLIMsgType::Ignored:
+ return str::Format(
+ _("Legacy commandline option %1% detected. This option is ignored."))
+ % NEGATIVEString(dashdash(old_r));
+ break;
+ }
+ return std::string();
+}
+
+void print_legacyCLIStr( Out & out, const std::string & old_r, const std::string & new_r, Out::Verbosity verbosity_r, LegacyCLIMsgType type_r )
+{
+ out.warning( legacyCLIStr( old_r, new_r, type_r), verbosity_r );
+}
void report_too_many_arguments(const std::string & specific_help); // deprecated
void report_too_many_arguments(Out & out, const std::string & specific_help);
+/** Say that too few arguments have been specified */
+void report_too_few_arguments( const std::string & specific_help );
+void report_too_few_arguments( Out & out, const std::string & specific_help );
+
/** Say the that either a aggregate option or a alias is required */
void report_alias_or_aggregate_required ( Out & out, const std::string & specific_help );
void print_verify_hint(Out & out);
+enum class LegacyCLIMsgType {
+ Local,
+ Global,
+ Ignored
+};
+std::string legacyCLIStr( const std::string & old_r, const std::string & new_r, LegacyCLIMsgType type_r );
+void print_legacyCLIStr(Out & out, const std::string & old_r, const std::string & new_r, Out::Verbosity verbosity_r = Out::NORMAL, LegacyCLIMsgType type_r = LegacyCLIMsgType::Local );
+
+
#endif /*MESSAGES_H_*/
#include <zypp/ResKind.h>
#include <zypp/RepoInfo.h>
#include <zypp/ZYppCommitPolicy.h>
+#include <zypp/base/Logger.h>
class Zypper;
class Table;
class Resolvable;
class Product;
class Pattern;
+ class Patch;
}
using namespace zypp;
BuildRequires: cmake >= 2.4.6
BuildRequires: gcc-c++ >= 4.7
BuildRequires: gettext-devel >= 0.15
-BuildRequires: libzypp-devel >= 17.7.0
+BuildRequires: libzypp-devel >= 17.8.0
BuildRequires: readline-devel >= 5.1
BuildRequires: libxml2-devel
Requires: procps