ref: refs/heads/master
commit 3a7b3492e965196c3d45c7b6b97c8cf87bbc1185
Author: Ján Kupec
Date: Sun Apr 26 16:49:09 2009 +0200
Config file handling improved.
- $HOME/.zypper.conf reading enabled
- --config option added to read custom file, default conf files
are ingored, if an existing file is specified
- do not fail if config can't be parsed, just log
---
src/Config.cc | 168 ++++++++++++++++++++++++++------------------------
src/Config.h | 2 +-
src/Zypper.cc | 11 ++--
src/Zypper.h | 1 -
src/utils/Augeas.cc | 94 ++++++++++++++++++++++-------
src/utils/Augeas.h | 10 +++-
6 files changed, 175 insertions(+), 111 deletions(-)
diff --git a/src/Config.cc b/src/Config.cc
index 99be31c..ad25dce 100644
--- a/src/Config.cc
+++ b/src/Config.cc
@@ -115,117 +115,123 @@ Config::Config()
, color_promptOption("grey")
{}
-void Config::read()
+void Config::read(const string & file)
{
- debug::Measure m("ReadConfig");
+ try
+ {
+ debug::Measure m("ReadConfig");
+ string s;
- Augeas augeas;
+ Augeas augeas(file);
- m.elapsed();
+ m.elapsed();
- string s;
+ // ---------------[ main ]--------------------------------------------------
- // ---------------[ main ]--------------------------------------------------
+ // TODO
- // TODO
+ // ---------------[ main ]--------------------------------------------------
- // ---------------[ main ]--------------------------------------------------
+ s = augeas.getOption(ConfigOption::SOLVER_INSTALL_RECOMMENDS.asString());
+ if (s.empty())
+ solver_installRecommends = ZConfig::instance().solver_onlyRequires();
+ else
+ solver_installRecommends = str::strToBool(s, true);
- s = augeas.getOption(ConfigOption::SOLVER_INSTALL_RECOMMENDS.asString());
- if (s.empty())
- solver_installRecommends = ZConfig::instance().solver_onlyRequires();
- else
- solver_installRecommends = str::strToBool(s, true);
+ // ---------------[ colors ]------------------------------------------------
- // ---------------[ colors ]------------------------------------------------
+ color_useColors = augeas.getOption(ConfigOption::COLOR_USE_COLORS.asString());
+ do_colors =
+ (color_useColors == "autodetect" && has_colors())
+ || color_useColors == "always";
- color_useColors = augeas.getOption(ConfigOption::COLOR_USE_COLORS.asString());
- do_colors =
- (color_useColors == "autodetect" && has_colors())
- || color_useColors == "always";
+ ////// color/background //////
- ////// color/background //////
+ s = augeas.getOption(ConfigOption::COLOR_BACKGROUND.asString());
+ if (s == "light")
+ color_background = true;
+ else if (!s.empty() && s != "dark")
+ ERR << "invalid color/background value: " << s << endl;
- s = augeas.getOption(ConfigOption::COLOR_BACKGROUND.asString());
- if (s == "light")
- color_background = true;
- else if (!s.empty() && s != "dark")
- ERR << "invalid color/background value: " << s << endl;
+ Color c("");
- Color c("");
+ ////// color/colorResult //////
- ////// color/colorResult //////
+ c = Color(augeas.getOption(ConfigOption::COLOR_RESULT.asString()));
+ if (c.value().empty())
+ {
+ // set a default for light background
+ if (color_background)
+ color_result = Color("black");
+ }
+ else
+ color_result = c;
- c = Color(augeas.getOption(ConfigOption::COLOR_RESULT.asString()));
- if (c.value().empty())
- {
- // set a default for light background
- if (color_background)
- color_result = Color("black");
- }
- else
- color_result = c;
+ ////// color/colorMsgStatus //////
- ////// color/colorMsgStatus //////
+ c = Color(augeas.getOption(ConfigOption::COLOR_MSG_STATUS.asString()));
+ if (c.value().empty())
+ {
+ // set a default for light background
+ if (color_background)
+ color_msgStatus = Color("default");
+ }
+ else
+ color_msgStatus = c;
- c = Color(augeas.getOption(ConfigOption::COLOR_MSG_STATUS.asString()));
- if (c.value().empty())
- {
- // set a default for light background
- if (color_background)
- color_msgStatus = Color("default");
- }
- else
- color_msgStatus = c;
+ ////// color/colorMsgError //////
- ////// color/colorMsgError //////
+ c = Color(augeas.getOption(ConfigOption::COLOR_MSG_ERROR.asString()));
+ if (!c.value().empty())
+ color_msgError = c;
- c = Color(augeas.getOption(ConfigOption::COLOR_MSG_ERROR.asString()));
- if (!c.value().empty())
- color_msgError = c;
+ ////// color/colorMsgWarning //////
- ////// color/colorMsgWarning //////
+ c = Color(augeas.getOption(ConfigOption::COLOR_MSG_WARNING.asString()));
+ if (c.value().empty())
+ {
+ // set a default for light background
+ if (color_background)
+ color_msgWarning = Color("brown");
+ }
+ else
+ color_msgWarning = c;
- c = Color(augeas.getOption(ConfigOption::COLOR_MSG_WARNING.asString()));
- if (c.value().empty())
- {
- // set a default for light background
- if (color_background)
- color_msgWarning = Color("brown");
- }
- else
- color_msgWarning = c;
+ ////// color/colorPositive //////
- ////// color/colorPositive //////
+ c = Color(augeas.getOption(ConfigOption::COLOR_POSITIVE.asString()));
+ if (!c.value().empty())
+ color_positive = c;
- c = Color(augeas.getOption(ConfigOption::COLOR_POSITIVE.asString()));
- if (!c.value().empty())
- color_positive = c;
+ ////// color/colorNegative //////
- ////// color/colorNegative //////
+ c = Color(augeas.getOption(ConfigOption::COLOR_NEGATIVE.asString()));
+ if (!c.value().empty())
+ color_negative = c;
- c = Color(augeas.getOption(ConfigOption::COLOR_NEGATIVE.asString()));
- if (!c.value().empty())
- color_negative = c;
+ ////// color/highlight //////
- ////// color/highlight //////
+ c = Color(augeas.getOption(ConfigOption::COLOR_HIGHLIGHT.asString()));
+ if (!c.value().empty())
+ color_highlight = c;
- c = Color(augeas.getOption(ConfigOption::COLOR_HIGHLIGHT.asString()));
- if (!c.value().empty())
- color_highlight = c;
+ ////// color/colorPromptOption //////
- ////// color/colorPromptOption //////
+ c = Color(augeas.getOption(ConfigOption::COLOR_PROMPT_OPTION.asString()));
+ if (c.value().empty())
+ {
+ // set a default for light background
+ if (color_background)
+ color_promptOption = Color("darkgrey");
+ }
+ else
+ color_promptOption = c;
- c = Color(augeas.getOption(ConfigOption::COLOR_PROMPT_OPTION.asString()));
- if (c.value().empty())
+ m.stop();
+ }
+ catch (Exception & e)
{
- // set a default for light background
- if (color_background)
- color_promptOption = Color("darkgrey");
+ DBG << "Augeas exception. No config read, sticking with defaults." << endl;
}
- else
- color_promptOption = c;
-
- m.stop();
}
diff --git a/src/Config.h b/src/Config.h
index 402387f..0c4397c 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -70,7 +70,7 @@ struct Config
Config();
/** Reads zypper.conf and stores the result */
- void read();
+ void read(const std::string & file = "");
bool solver_installRecommends;
diff --git a/src/Zypper.cc b/src/Zypper.cc
index 6fd8072..6eaa889 100644
--- a/src/Zypper.cc
+++ b/src/Zypper.cc
@@ -103,7 +103,6 @@ int Zypper::main(int argc, char ** argv)
// parse global options and the command
try {
- readConfig();
processGlobalOptions();
}
catch (const ExitRequestException & e)
@@ -148,16 +147,13 @@ Out & Zypper::out()
ZYPP_THROW(ExitRequestException("no output writer"));
}
-void Zypper::readConfig()
-{
- _config.read();
-}
void print_main_help(Zypper & zypper)
{
static string help_global_options = _(" Global Options:\n"
"\t--help, -h\t\tHelp.\n"
"\t--version, -V\t\tOutput the version number.\n"
+ "\t--config, -c\t\tUse specified config file instead of the deafult.\n"
"\t--quiet, -q\t\tSuppress normal output, print only error\n"
"\t\t\t\tmessages.\n"
"\t--verbose, -v\t\tIncrease verbosity.\n"
@@ -342,6 +338,7 @@ void Zypper::processGlobalOptions()
{"no-cd", no_argument, 0, 0 },
{"no-remote", no_argument, 0, 0 },
{"xmlout", no_argument, 0, 'x'},
+ {"config", required_argument, 0, 'c'},
{0, 0, 0, 0}
};
@@ -355,6 +352,10 @@ void Zypper::processGlobalOptions()
parsed_opts::const_iterator it;
+ // read config from specified file or default config files
+ _config.read(
+ (it = gopts.find("config")) != gopts.end() ? it->second.front() : "");
+
// ====== output setup ======
// depends on global options, that's we set it up here
//! \todo create a default in the zypper constructor, recreate here.
diff --git a/src/Zypper.h b/src/Zypper.h
index d5189da..0eead52 100644
--- a/src/Zypper.h
+++ b/src/Zypper.h
@@ -188,7 +188,6 @@ public:
private:
Zypper();
- void readConfig();
void processGlobalOptions();
void processCommandOptions();
void commandShell();
diff --git a/src/utils/Augeas.cc b/src/utils/Augeas.cc
index d1d7578..e3580f1 100644
--- a/src/utils/Augeas.cc
+++ b/src/utils/Augeas.cc
@@ -8,41 +8,84 @@
#include
#include "zypp/base/Logger.h"
+#include "zypp/Pathname.h"
#include "Zypper.h"
#include "utils/Augeas.h"
using namespace zypp;
using namespace std;
-Augeas::Augeas()
+Augeas::Augeas(const string & file)
: _augeas(NULL), _got_global_zypper_conf(false), _got_user_zypper_conf(false)
{
MIL << "Going to read zypper config using Augeas..." << endl;
- //! \todo use specified root dir
- _augeas = ::aug_init(NULL, "/usr/share/zypper", AUG_NO_STDINC);
-
+ // init
+ _augeas = ::aug_init(NULL, "/usr/share/zypper", AUG_NO_STDINC | AUG_NO_LOAD);
if (_augeas == NULL)
ZYPP_THROW(Exception(_("Cannot initialize configuration file parser.")));
+ // tell augeas which file to load
+ // if file is specified, try to load the file, fall back to default files
+ // default - /etc/zypp/zypper.conf & $HOME/.zypper.conf
+ Pathname filepath(file);
+ bool want_custom = false;
+ if (!file.empty() && PathInfo(filepath).isExist())
+ {
+ want_custom = true;
+ if (filepath.relative())
+ {
+ string wd = ::getenv("PWD");
+ filepath = wd / filepath;
+ }
- _got_global_zypper_conf =
- ::aug_get(_augeas, "/files/etc/zypp/zypper.conf", NULL) != 0;
+ if (::aug_set(_augeas, "/augeas/load/ZYpper/incl", filepath.asString().c_str()) != 0)
+ ZYPP_THROW(Exception(_("Augeas error: setting config file to load failed.")));
+ }
+ else
+ {
+ _homedir = ::getenv("HOME");
+ if (_homedir.empty())
+ WAR << "Cannot figure out user's home directory. Skipping user's config." << endl;
+ else
+ {
+ // add $HOME/.zypper.conf; /etc/zypp/zypper.conf should already be included
+ filepath = _homedir + "/.zypper.conf";
+ if (::aug_set(_augeas, "/augeas/load/ZYpper/incl[2]", filepath.asString().c_str()) != 0)
+ ZYPP_THROW(Exception(_("Augeas error: setting config file to load failed.")));
+ }
+ }
+ // load the file
+ if (aug_load(_augeas) != 0)
+ ZYPP_THROW(Exception(_("Could not parse the config files.")));
+
+ // collect eventual errors
const char *value[1] = {};
string error;
- if (::aug_get(_augeas, "/augeas/files/etc/zypp/zypper.conf/error/message", value))
- error = value[0];
-
- _homedir = ::getenv("HOME");
- if (_homedir.empty())
- WAR << "Cannot figure out user's home directory." << endl;
+ if (want_custom)
+ _user_conf_path = "/files" + filepath.asString();
else
{
- //! \todo cherry-pick this file as soon as the API allows it
- string user_zypper_conf = "/files" + _homedir + "/.zypper.conf";
+ if (!_homedir.empty())
+ _user_conf_path = "/files" + _homedir + "/.zypper.conf";
+
+ // global conf errors
+ _got_global_zypper_conf =
+ ::aug_get(_augeas, "/files/etc/zypp/zypper.conf", NULL) != 0;
+ if (::aug_get(_augeas, "/augeas/files/etc/zypp/zypper.conf/error/message", value))
+ error = value[0];
+
+ }
+
+ // user conf errors
+ if (!_user_conf_path.empty())
+ {
_got_user_zypper_conf =
- ::aug_get(_augeas, user_zypper_conf.c_str(), NULL) != 0;
+ ::aug_get(_augeas, _user_conf_path.c_str(), NULL) != 0;
+ string user_conf_err = "/augeas" + _user_conf_path + "/error/message";
+ if (::aug_get(_augeas, user_conf_err.c_str(), value))
+ error += string("\n") + value[0];
}
if (!_got_global_zypper_conf && !_got_user_zypper_conf)
@@ -58,8 +101,13 @@ Augeas::Augeas()
}
MIL << "Done reading conf files:" << endl;
- MIL << "user conf read: " << (_got_user_zypper_conf ? "yes" : "no") << endl;
- MIL << "global conf read: " << (_got_global_zypper_conf ? "yes" : "no") << endl;
+ if (want_custom)
+ MIL << "custom conf read: " << (_got_user_zypper_conf ? "yes" : "no") << endl;
+ else
+ {
+ MIL << "user conf read: " << (_got_user_zypper_conf ? "yes" : "no") << endl;
+ MIL << "global conf read: " << (_got_global_zypper_conf ? "yes" : "no") << endl;
+ }
}
// ---------------------------------------------------------------------------
@@ -78,10 +126,12 @@ static string global_option_path(
return "/files/etc/zypp/zypper.conf/" + section + "/*/" + option;
}
-static string user_option_path(
- const string & section, const string & option, const string & homedir)
+string Augeas::userOptionPath(
+ const string & section, const string & option) const
{
- return "/files" + homedir + "/.zypper.conf/" + section + "/*/" + option;
+ if (_user_conf_path.empty())
+ return "(empty)";
+ return _user_conf_path + "/" + section + "/*/" + option;
}
// ---------------------------------------------------------------------------
@@ -118,7 +168,7 @@ string Augeas::getOption(const string & option) const
if (_got_user_zypper_conf)
{
- string augpath_u = user_option_path(opt[0], opt[1], _homedir);
+ string augpath_u = userOptionPath(opt[0], opt[1]);
string result = get(augpath_u);
if (_last_get_result && !isCommented(opt[0], opt[1], false))
return result;
@@ -147,7 +197,7 @@ TriBool Augeas::isCommented(
Pathname path(global ?
global_option_path(section, option) :
- user_option_path(section, option, _homedir));
+ userOptionPath(section, option));
TriBool result;
diff --git a/src/utils/Augeas.h b/src/utils/Augeas.h
index d0feebf..db2248d 100644
--- a/src/utils/Augeas.h
+++ b/src/utils/Augeas.h
@@ -28,7 +28,7 @@ extern "C"
class Augeas : private zypp::base::NonCopyable
{
public:
- Augeas();
+ Augeas(const std::string & file = "");
~Augeas();
std::string get(const std::string & augpath) const;
@@ -42,6 +42,9 @@ public:
{ return _augeas; }
private:
+ std::string userOptionPath(
+ const std::string & section, const std::string & option) const;
+
zypp::TriBool isCommented(const std::string & section,
const std::string & option,
bool global) const;
@@ -49,6 +52,11 @@ private:
private:
::augeas * _augeas;
std::string _homedir;
+ /**
+ * Path of the config file in the augeas tree,
+ * e.g. /files/path/to/user/zypper.conf
+ */
+ std::string _user_conf_path;
bool _got_global_zypper_conf;
bool _got_user_zypper_conf;
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org