aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-04-15 01:45:47 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-04-15 01:45:47 +0000
commit1a7f3d720fb2b076573a433623e189a48af7343b (patch)
treefec38a911b857af40a38306d93239677f0a1af9b
parent9b2c102e0c13f7f00adb8327b99332ed83e38edf (diff)
downloadpaludis-1a7f3d720fb2b076573a433623e189a48af7343b.tar.gz
paludis-1a7f3d720fb2b076573a433623e189a48af7343b.tar.xz
Dynamic config files
-rw-r--r--doc/configuration.html.skel52
-rw-r--r--paludis/environments/paludis/paludis_config.cc289
2 files changed, 294 insertions, 47 deletions
diff --git a/doc/configuration.html.skel b/doc/configuration.html.skel
index a4e346e..9e31d6a 100644
--- a/doc/configuration.html.skel
+++ b/doc/configuration.html.skel
@@ -81,6 +81,9 @@ general operation. Recognised keys are:</p>
or <code>-try</code> and any <code>EAPI</code> containing the string <code>paludis</code>.</dd>
</dl>
+<p>If <code>environment.conf</code> does not exist and <code>environment.bash</code>
+does, Paludis executes the latter and pretends that its stdout is the content of the former.</p>
+
<h3>The use.conf File</h3>
<p>User <code>USE</code> preferences are controlled by the <code>use.conf</code>
@@ -114,8 +117,11 @@ x11-libs/gtk+:2 tiff
<p>Note that if a package matches multiple lines, <em>all</em> of these lines will
be considered, not just the best or last match.</p>
-<p>If a <code>use.conf.d</code> directory exists, any file named <code>*.conf</code>
-in this directory is treated as if it were appended to the main file.</p>
+<p>If <code>use.bash</code> exists, it is executed and its stdout is used as if
+it were appended to the main file. If a <code>use.conf.d</code> directory
+exists, any file named <code>*.conf</code> in this directory is treated as if it
+were appended to the main file, and any file named <code>*.bash</code> is
+executed and has its stdout used as if it were appended to the main file.</p>
<h3>The keywords.conf File</h3>
@@ -148,8 +154,11 @@ package being masked, as the package is stabilised.</p>
keywords from a less specific match. The <code>*</code> special keyword can be
used to accept anything.</p>
-<p>If a <code>keywords.conf.d</code> directory exists, any file named <code>*.conf</code>
-in this directory is treated as if it were appended to the main file.</p>
+<p>If <code>keywords.bash</code> exists, it is executed and its stdout is used as if
+it were appended to the main file. If a <code>keywords.conf.d</code> directory
+exists, any file named <code>*.conf</code> in this directory is treated as if it
+were appended to the main file, and any file named <code>*.bash</code> is
+executed and has its stdout used as if it were appended to the main file.</p>
<h3>The package_mask.conf File</h3>
@@ -166,8 +175,11 @@ per line. For example:</p>
app-editors/gvim
</pre>
-<p>If a <code>package_unmask.conf.d</code> directory exists, any file named <code>*.conf</code>
-in this directory is treated as if it were appended to the main file.</p>
+<p>If <code>package_mask.bash</code> exists, it is executed and its stdout is used as if
+it were appended to the main file. If a <code>package_mask.conf.d</code> directory
+exists, any file named <code>*.conf</code> in this directory is treated as if it
+were appended to the main file, and any file named <code>*.bash</code> is
+executed and has its stdout used as if it were appended to the main file.</p>
<h3>The package_unmask.conf File</h3>
@@ -180,8 +192,11 @@ in this directory is treated as if it were appended to the main file.</p>
=media-sound/banshee-0.11.0
</pre>
-<p>If a <code>package_mask.conf.d</code> directory exists, any file named <code>*.conf</code>
-in this directory is treated as if it were appended to the main file.</p>
+<p>If <code>package_unmask.bash</code> exists, it is executed and its stdout is used as if
+it were appended to the main file. If a <code>package_unmask.conf.d</code> directory
+exists, any file named <code>*.conf</code> in this directory is treated as if it
+were appended to the main file, and any file named <code>*.bash</code> is
+executed and has its stdout used as if it were appended to the main file.</p>
<h3>The licenses.conf File</h3>
@@ -199,8 +214,11 @@ filtering is desired, use:</p>
app-editors/vim-core vim
</pre>
-<p>If a <code>licenses.conf.d</code> directory exists, any file named <code>*.conf</code>
-in this directory is treated as if it were appended to the main file.</p>
+<p>If <code>licenses.bash</code> exists, it is executed and its stdout is used as if
+it were appended to the main file. If a <code>licenses.conf.d</code> directory
+exists, any file named <code>*.conf</code> in this directory is treated as if it
+were appended to the main file, and any file named <code>*.bash</code> is
+executed and has its stdout used as if it were appended to the main file.</p>
<h3>The mirrors.conf File</h3>
@@ -214,8 +232,11 @@ any other location for all files. For example:</p>
gentoo http://gentoo.blueyonder.co.uk/distfiles
</pre>
-<p>If a <code>mirrors.conf.d</code> directory exists, any file named <code>*.conf</code>
-in this directory is treated as if it were appended to the main file.</p>
+<p>If <code>mirrors.bash</code> exists, it is executed and its stdout is used as if
+it were appended to the main file. If a <code>mirrors.conf.d</code> directory
+exists, any file named <code>*.conf</code> in this directory is treated as if it
+were appended to the main file, and any file named <code>*.bash</code> is
+executed and has its stdout used as if it were appended to the main file.</p>
<h3>The bashrc File</h3>
@@ -232,6 +253,10 @@ variable <code>${ROOT}</code> is defined based upon <code>specpath</code>. All
files must define a <code>format =</code> key; depending upon the value used, other
optional and mandatory keys are available.</p>
+<p>Files named <code>*.bash</code> in the <code>repositories/</code> subdirectory
+are executed by Paludis and their stdout is used as if it were a normal repository
+<code>.conf</code> file.</p>
+
<p>Each repository can have a key named <code>importance</code>. This is used when
two different repositories contain an identical package atom (e.g. foo/bar-1.0).
The repository with the higher importance will always be chosen first. If not
@@ -243,6 +268,9 @@ does <strong>not</strong> live in the <code>repositories/</code> subdirectory).
Keys in this file are overridden by identically named keys in individual
configuration files.</p>
+<p>If <code>repository_defaults.conf</code> does not exist and <code>repository_defaults.bash</code>
+does, Paludis executes the latter and pretends that its stdout is the content of the former.</p>
+
<h4>ebuild Format Repositories</h4>
<p>The following keys are available for <code>format = ebuild</code>:</p>
diff --git a/paludis/environments/paludis/paludis_config.cc b/paludis/environments/paludis/paludis_config.cc
index 4f9d6ce..d932230 100644
--- a/paludis/environments/paludis/paludis_config.cc
+++ b/paludis/environments/paludis/paludis_config.cc
@@ -28,6 +28,7 @@
#include <paludis/util/fs_entry.hh>
#include <paludis/util/is_file_with_extension.hh>
#include <paludis/util/log.hh>
+#include <paludis/util/pstream.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/sr.hh>
#include <paludis/util/system.hh>
@@ -152,25 +153,45 @@ namespace paludis
return;
Context context("When loading environment.conf:");
- if (! (FSEntry(config_dir) / "environment.conf").exists())
- {
- Log::get_instance()->message(ll_debug, lc_context,
- "No environment.conf exists in '" + stringify(config_dir) + "'");
- return;
- }
- KeyValueConfigFile f(FSEntry(config_dir) / "environment.conf", KeyValueConfigFileOptions());
- if (! f.get("reduced_username").empty())
+ std::tr1::shared_ptr<KeyValueConfigFile> kv;
+
+ if ((FSEntry(config_dir) / "environment.conf").exists())
+ kv.reset(new KeyValueConfigFile(FSEntry(config_dir) / "environment.conf", KeyValueConfigFileOptions()));
+ else if ((FSEntry(config_dir) / "environment.bash").exists())
{
- reduced_username = f.get("reduced_username");
- Log::get_instance()->message(ll_debug, lc_context,
- "loaded key 'reduced_username' = '" + reduced_username + "'");
+ Command cmd(Command("bash '" + stringify(FSEntry(config_dir) / "environment.bash") + "'")
+ .with_setenv("PALUDIS_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
+ .with_stderr_prefix("environment.bash> "));
+ PStream s(cmd);
+ kv.reset(new KeyValueConfigFile(s, KeyValueConfigFileOptions()));
+
+ if (s.exit_status() != 0)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Script '" + stringify(FSEntry(config_dir) / "environment.bash")
+ + "' returned non-zero exit status '" + stringify(s.exit_status()) + "'");
+ kv.reset();
+ }
}
else
- Log::get_instance()->message(ll_debug, lc_context,
- "Key 'reduced_username' is unset, using '" + reduced_username + "'");
+ Log::get_instance()->message(ll_debug, lc_context, "No environment.conf or environment.bash in '"
+ + config_dir + "'");
- accept_breaks_portage = f.get("portage_compatible").empty();
+ if (kv)
+ {
+ if (! kv->get("reduced_username").empty())
+ {
+ reduced_username = kv->get("reduced_username");
+ Log::get_instance()->message(ll_debug, lc_context,
+ "loaded key 'reduced_username' = '" + reduced_username + "'");
+ }
+ else
+ Log::get_instance()->message(ll_debug, lc_context,
+ "Key 'reduced_username' is unset, using '" + reduced_username + "'");
+
+ accept_breaks_portage = kv->get("portage_compatible").empty();
+ }
has_environment_conf = true;
}
@@ -379,8 +400,17 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
if ((local_config_dir / "repository_defaults.conf").exists())
{
KeyValueConfigFile defaults_file(local_config_dir / "repository_defaults.conf", KeyValueConfigFileOptions());
- std::copy(defaults_file.begin(), defaults_file.end(),
- conf_vars->inserter());
+ std::copy(defaults_file.begin(), defaults_file.end(), conf_vars->inserter());
+ }
+ else if ((local_config_dir / "repository_defaults.bash").exists())
+ {
+ Command cmd(Command("bash '" + stringify(local_config_dir / "repository_defaults.bash") + "'")
+ .with_setenv("PALUDIS_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
+ .with_stderr_prefix("repository_defaults.bash> "));
+ PStream s(cmd);
+ KeyValueConfigFile defaults_file(s, KeyValueConfigFileOptions());
+ std::copy(defaults_file.begin(), defaults_file.end(), conf_vars->inserter());
}
std::list<FSEntry> dirs;
@@ -395,6 +425,8 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
std::copy(DirIterator(*dir), DirIterator(),
filter_inserter(std::back_inserter(repo_files), IsFileWithExtension(".conf")));
+ std::copy(DirIterator(*dir), DirIterator(),
+ filter_inserter(std::back_inserter(repo_files), IsFileWithExtension(".bash")));
}
std::list<std::tr1::shared_ptr<AssociativeCollection<std::string, std::string> > > later_keys;
@@ -403,18 +435,39 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
{
Context local_context("When reading repository file '" + stringify(*repo_file) + "':");
- KeyValueConfigFile k(*repo_file, KeyValueConfigFileOptions(), KeyValueConfigFile::Defaults(conf_vars));
+ std::tr1::shared_ptr<KeyValueConfigFile> kv;
+ if (IsFileWithExtension(".bash")(*repo_file))
+ {
+ Command cmd(Command("bash '" + stringify(*repo_file) + "'")
+ .with_setenv("PALUDIS_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
+ .with_stderr_prefix(repo_file->basename() + "> "));
+ PStream s(cmd);
+ kv.reset(new KeyValueConfigFile(s, KeyValueConfigFileOptions(), KeyValueConfigFile::Defaults(conf_vars)));
+
+ if (s.exit_status() != 0)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Script '" + stringify(*repo_file)
+ + "' returned non-zero exit status '" + stringify(s.exit_status()) + "'");
+ kv.reset();
+ }
+ }
+ else
+ kv.reset(new KeyValueConfigFile(*repo_file, KeyValueConfigFileOptions(), KeyValueConfigFile::Defaults(conf_vars)));
- std::string format(k.get("format"));
+ if (! kv)
+ continue;
+
+ std::string format(kv->get("format"));
if (format.empty())
throw PaludisConfigError("Key 'format' not specified or empty");
- int importance(k.get("master_repository").empty() ? 0 : 10);
- if (! k.get("importance").empty())
- importance = destringify<int>(k.get("importance"));
+ int importance(kv->get("master_repository").empty() ? 0 : 10);
+ if (! kv->get("importance").empty())
+ importance = destringify<int>(kv->get("importance"));
std::tr1::shared_ptr<AssociativeCollection<std::string, std::string> > keys(
- new AssociativeCollection<std::string, std::string>::Concrete(k.begin(), k.end()));
+ new AssociativeCollection<std::string, std::string>::Concrete(kv->begin(), kv->end()));
keys->erase("importance");
keys->insert("importance", stringify(importance));
@@ -425,7 +478,7 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
keys->erase("root");
keys->insert("root", root_prefix.empty() ? "/" : root_prefix);
- if (! k.get("master_repository").empty())
+ if (! kv->get("master_repository").empty())
{
Log::get_instance()->message(ll_debug, lc_context, "Delaying '" + stringify(*repo_file) +
"' because it uses master_repository");
@@ -451,9 +504,14 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
{
std::list<FSEntry> files;
files.push_back(local_config_dir / "keywords.conf");
+ files.push_back(local_config_dir / "keywords.bash");
if ((local_config_dir / "keywords.conf.d").exists())
+ {
std::copy(DirIterator(local_config_dir / "keywords.conf.d"), DirIterator(),
filter_inserter(std::back_inserter(files), IsFileWithExtension(".conf")));
+ std::copy(DirIterator(local_config_dir / "keywords.conf.d"), DirIterator(),
+ filter_inserter(std::back_inserter(files), IsFileWithExtension(".bash")));
+ }
for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
file != file_end ; ++file)
@@ -463,8 +521,30 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
if (! file->is_regular_file())
continue;
- LineConfigFile f(*file, LineConfigFileOptions());
- for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ std::tr1::shared_ptr<LineConfigFile> f;
+ if (IsFileWithExtension(".bash")(*file))
+ {
+ Command cmd(Command("bash '" + stringify(*file) + "'")
+ .with_setenv("PALUDIS_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
+ .with_stderr_prefix(file->basename() + "> "));
+ PStream s(cmd);
+ f.reset(new LineConfigFile(s, LineConfigFileOptions()));
+
+ if (s.exit_status() != 0)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Script '" + stringify(*file)
+ + "' returned non-zero exit status '" + stringify(s.exit_status()) + "'");
+ f.reset();
+ }
+ }
+ else
+ f.reset(new LineConfigFile(*file, LineConfigFileOptions()));
+
+ if (! f)
+ continue;
+
+ for (LineConfigFile::Iterator line(f->begin()), line_end(f->end()) ;
line != line_end ; ++line)
{
std::vector<std::string> tokens;
@@ -507,9 +587,14 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
{
std::list<FSEntry> files;
files.push_back(local_config_dir / "licenses.conf");
+ files.push_back(local_config_dir / "licenses.bash");
if ((local_config_dir / "licenses.conf.d").exists())
+ {
std::copy(DirIterator(local_config_dir / "licenses.conf.d"), DirIterator(),
filter_inserter(std::back_inserter(files), IsFileWithExtension(".conf")));
+ std::copy(DirIterator(local_config_dir / "licenses.conf.d"), DirIterator(),
+ filter_inserter(std::back_inserter(files), IsFileWithExtension(".bash")));
+ }
for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
file != file_end ; ++file)
@@ -519,8 +604,30 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
if (! file->is_regular_file())
continue;
- LineConfigFile f(*file, LineConfigFileOptions());
- for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ std::tr1::shared_ptr<LineConfigFile> f;
+ if (IsFileWithExtension(".bash")(*file))
+ {
+ Command cmd(Command("bash '" + stringify(*file) + "'")
+ .with_setenv("PALUDIS_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
+ .with_stderr_prefix(file->basename() + "> "));
+ PStream s(cmd);
+ f.reset(new LineConfigFile(s, LineConfigFileOptions()));
+
+ if (s.exit_status() != 0)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Script '" + stringify(*file)
+ + "' returned non-zero exit status '" + stringify(s.exit_status()) + "'");
+ f.reset();
+ }
+ }
+ else
+ f.reset(new LineConfigFile(*file, LineConfigFileOptions()));
+
+ if (! f)
+ continue;
+
+ for (LineConfigFile::Iterator line(f->begin()), line_end(f->end()) ;
line != line_end ; ++line)
{
std::vector<std::string> tokens;
@@ -561,9 +668,14 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
{
std::list<FSEntry> files;
files.push_back(local_config_dir / "package_mask.conf");
+ files.push_back(local_config_dir / "package_mask.bash");
if ((local_config_dir / "package_mask.conf.d").exists())
+ {
std::copy(DirIterator(local_config_dir / "package_mask.conf.d"), DirIterator(),
filter_inserter(std::back_inserter(files), IsFileWithExtension(".conf")));
+ std::copy(DirIterator(local_config_dir / "package_mask.conf.d"), DirIterator(),
+ filter_inserter(std::back_inserter(files), IsFileWithExtension(".bash")));
+ }
for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
file != file_end ; ++file)
@@ -573,8 +685,31 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
if (! file->is_regular_file())
continue;
- LineConfigFile f(*file, LineConfigFileOptions());
- for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ std::tr1::shared_ptr<LineConfigFile> f;
+
+ if (IsFileWithExtension(".bash")(*file))
+ {
+ Command cmd(Command("bash '" + stringify(*file) + "'")
+ .with_setenv("PALUDIS_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
+ .with_stderr_prefix(file->basename() + "> "));
+ PStream s(cmd);
+ f.reset(new LineConfigFile(s, LineConfigFileOptions()));
+
+ if (s.exit_status() != 0)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Script '" + stringify(*file)
+ + "' returned non-zero exit status '" + stringify(s.exit_status()) + "'");
+ f.reset();
+ }
+ }
+ else
+ f.reset(new LineConfigFile(*file, LineConfigFileOptions()));
+
+ if (! f)
+ continue;
+
+ for (LineConfigFile::Iterator line(f->begin()), line_end(f->end()) ;
line != line_end ; ++line)
{
if (line->empty())
@@ -601,9 +736,14 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
{
std::list<FSEntry> files;
files.push_back(local_config_dir / "package_unmask.conf");
+ files.push_back(local_config_dir / "package_unmask.bash");
if ((local_config_dir / "package_unmask.conf.d").exists())
+ {
std::copy(DirIterator(local_config_dir / "package_unmask.conf.d"), DirIterator(),
filter_inserter(std::back_inserter(files), IsFileWithExtension(".conf")));
+ std::copy(DirIterator(local_config_dir / "package_unmask.conf.d"), DirIterator(),
+ filter_inserter(std::back_inserter(files), IsFileWithExtension(".bash")));
+ }
for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
file != file_end ; ++file)
@@ -613,8 +753,31 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
if (! file->is_regular_file())
continue;
- LineConfigFile f(*file, LineConfigFileOptions());
- for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ std::tr1::shared_ptr<LineConfigFile> f;
+
+ if (IsFileWithExtension(".bash")(*file))
+ {
+ Command cmd(Command("bash '" + stringify(*file) + "'")
+ .with_setenv("PALUDIS_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
+ .with_stderr_prefix(file->basename() + "> "));
+ PStream s(cmd);
+ f.reset(new LineConfigFile(s, LineConfigFileOptions()));
+
+ if (s.exit_status() != 0)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Script '" + stringify(*file)
+ + "' returned non-zero exit status '" + stringify(s.exit_status()) + "'");
+ f.reset();
+ }
+ }
+ else
+ f.reset(new LineConfigFile(*file, LineConfigFileOptions()));
+
+ if (! f)
+ continue;
+
+ for (LineConfigFile::Iterator line(f->begin()), line_end(f->end()) ;
line != line_end ; ++line)
{
if (line->empty())
@@ -641,9 +804,14 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
{
std::list<FSEntry> files;
files.push_back(local_config_dir / "use.conf");
+ files.push_back(local_config_dir / "use.bash");
if ((local_config_dir / "use.conf.d").exists())
+ {
std::copy(DirIterator(local_config_dir / "use.conf.d"), DirIterator(),
filter_inserter(std::back_inserter(files), IsFileWithExtension(".conf")));
+ std::copy(DirIterator(local_config_dir / "use.conf.d"), DirIterator(),
+ filter_inserter(std::back_inserter(files), IsFileWithExtension(".bash")));
+ }
for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
file != file_end ; ++file)
@@ -653,8 +821,31 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
if (! file->is_regular_file())
continue;
- LineConfigFile f(*file, LineConfigFileOptions());
- for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ std::tr1::shared_ptr<LineConfigFile> f;
+
+ if (IsFileWithExtension(".bash")(*file))
+ {
+ Command cmd(Command("bash '" + stringify(*file) + "'")
+ .with_setenv("PALUDIS_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
+ .with_stderr_prefix(file->basename() + "> "));
+ PStream s(cmd);
+ f.reset(new LineConfigFile(s, LineConfigFileOptions()));
+
+ if (s.exit_status() != 0)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Script '" + stringify(*file)
+ + "' returned non-zero exit status '" + stringify(s.exit_status()) + "'");
+ f.reset();
+ }
+ }
+ else
+ f.reset(new LineConfigFile(*file, LineConfigFileOptions()));
+
+ if (! f)
+ continue;
+
+ for (LineConfigFile::Iterator line(f->begin()), line_end(f->end()) ;
line != line_end ; ++line)
{
std::vector<std::string> tokens;
@@ -773,9 +964,14 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
{
std::list<FSEntry> files;
files.push_back(local_config_dir / "mirrors.conf");
+ files.push_back(local_config_dir / "mirrors.bash");
if ((local_config_dir / "mirrors.conf.d").exists())
+ {
std::copy(DirIterator(local_config_dir / "mirrors.conf.d"), DirIterator(),
filter_inserter(std::back_inserter(files), IsFileWithExtension(".conf")));
+ std::copy(DirIterator(local_config_dir / "mirrors.conf.d"), DirIterator(),
+ filter_inserter(std::back_inserter(files), IsFileWithExtension(".bash")));
+ }
for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
file != file_end ; ++file)
@@ -785,8 +981,31 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
if (! file->is_regular_file())
continue;
- LineConfigFile f(*file, LineConfigFileOptions());
- for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ std::tr1::shared_ptr<LineConfigFile> f;
+
+ if (IsFileWithExtension(".bash")(*file))
+ {
+ Command cmd(Command("bash '" + stringify(*file) + "'")
+ .with_setenv("PALUDIS_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
+ .with_stderr_prefix(file->basename() + "> "));
+ PStream s(cmd);
+ f.reset(new LineConfigFile(s, LineConfigFileOptions()));
+
+ if (s.exit_status() != 0)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Script '" + stringify(*file)
+ + "' returned non-zero exit status '" + stringify(s.exit_status()) + "'");
+ f.reset();
+ }
+ }
+ else
+ f.reset(new LineConfigFile(*file, LineConfigFileOptions()));
+
+ if (! f)
+ continue;
+
+ for (LineConfigFile::Iterator line(f->begin()), line_end(f->end()) ;
line != line_end ; ++line)
{
std::vector<std::string> m;