aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-01-14 06:06:38 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-01-14 06:06:38 +0000
commit9c9429645a80c3716a30dec9a27ad75a690506a8 (patch)
treef1e80573f309a3eec4a1939537f958b189b56e46
parent1acef90672831ce435f96fdacaed90527fd9cbf3 (diff)
downloadpaludis-9c9429645a80c3716a30dec9a27ad75a690506a8.tar.gz
paludis-9c9429645a80c3716a30dec9a27ad75a690506a8.tar.xz
Add environment variables that hooks can use to read commandline parameters. Fixes: ticket:7.
-rw-r--r--doc/hooks.html.skel33
-rw-r--r--paludis/args/args_handler.cc16
-rw-r--r--paludis/args/args_handler.hh10
-rw-r--r--paludis/args/args_visitor.cc49
-rw-r--r--paludis/args/args_visitor.hh10
-rw-r--r--src/clients/paludis/paludis.cc2
6 files changed, 95 insertions, 25 deletions
diff --git a/doc/hooks.html.skel b/doc/hooks.html.skel
index 90238d6..19228d4 100644
--- a/doc/hooks.html.skel
+++ b/doc/hooks.html.skel
@@ -63,7 +63,7 @@ that is executed when a particular well defined action occurs.</p>
<p>In general, certain special environment variables will be set. <code>HOOK</code> will contain
the name of the hook. For <code>all</code> hooks, <code>TARGETS</code> will contain the targets
for the operation. For non-<code>all</code> hooks, <code>TARGET</code> will contain the current
-target.</p>
+target. The <code>PALUDIS_CMDLINE</code> variables described below are also available.</p>
<h4>Ebuild Hooks</h4>
@@ -126,8 +126,9 @@ target.</p>
<li><code>ebuild_postrm_post</code></li>
</ul>
-<p>As well as the full ebuild environment, the <code>HOOK</code> environment variable
-will contain the name of the hook being called.</p>
+<p>As well as the full ebuild environment, the <code>HOOK</code> environment
+variable will contain the name of the hook being called. The
+<code>PALUDIS_CMDLINE</code> variables described below are also available.</p>
<h4>Ebuild Message Hooks</h4>
@@ -141,8 +142,9 @@ will contain the name of the hook being called.</p>
</ul>
<p>The <code>HOOK</code> environment variable will contain the name of the hook
-being called, and the <code>MESSAGE</code> environment variable will contain the
-message being passed to the function.</p>
+being called, and the <code>MESSAGE</code> environment variable will contain
+the message being passed to the function. The <code>PALUDIS_CMDLINE</code>
+variables described below are also available.</p>
<h3>User Defined Hooks</h3>
@@ -172,6 +174,27 @@ are not suitably general to be enabled by default -- these live in
<code>DATADIR/paludis/hooks/demos/</code>. You may also find the default
hooks useful -- these live in various places in <code>LIBEXECDIR/paludis/hooks/</code>.</p>
+<h3>The <code>PALUDIS_CMDLINE</code> Variables</h3>
+
+<p>Sometimes hooks need access to the commandline used to invoke
+<code>paludis</code>. However, manual parsing of the commandline by hooks will
+lead to bugs when people forget to emulate certain behaviour (say, short
+options, aliases or <code>--</code> support). To work around this issue,
+Paludis provides environment variables prefixed <code>PALUDIS_CMDLINE_</code>
+that specify the parsed command line:</p>
+
+<ul>
+ <li>The <code>PALUDIS_CMDLINE_PARAMS</code> variable contains the parameters (that is,
+ the parts that aren't <code>-x</code> or <code>--blah</code> or values for these).</li>
+
+ <li>For each <code>--param-name</code>, <code>PALUDIS_CMDLINE_param_name</code> (note
+ the case and the underscores) is set. If <code>--param-name</code> takes an argument,
+ this argument is used for the environment variable's value.</li>
+
+ <li>For short options (<code>-x</code>) and aliases, the appropriate long option's
+ variable is set instead.</li>
+</ul>
+
@FOOTER@
</body>
</html>
diff --git a/paludis/args/args_handler.cc b/paludis/args/args_handler.cc
index 04e7e6a..64735b1 100644
--- a/paludis/args/args_handler.cc
+++ b/paludis/args/args_handler.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -20,6 +20,7 @@
#include "args.hh"
#include "args_dumper.hh"
#include <paludis/util/system.hh>
+#include <paludis/util/join.hh>
#include <algorithm>
#include <sstream>
#include <list>
@@ -83,7 +84,8 @@ ArgsHandler::add(ArgsGroup * const g)
}
void
-ArgsHandler::run(const int argc, const char * const * const argv, const std::string & env_var)
+ArgsHandler::run(const int argc, const char * const * const argv, const std::string & env_var,
+ const std::string & env_prefix)
{
std::list<std::string> args;
std::string env_options;
@@ -93,10 +95,10 @@ ArgsHandler::run(const int argc, const char * const * const argv, const std::str
std::istringstream iss(env_options);
std::string option;
- while(iss.good())
+ while (iss.good())
{
iss >> option;
- if(!option.empty())
+ if (!option.empty())
args.push_back(option);
}
@@ -104,7 +106,7 @@ ArgsHandler::run(const int argc, const char * const * const argv, const std::str
libwrapiter::ForwardIterator<ArgsVisitor, std::string> argit(args.begin()), arge(args.end());
- ArgsVisitor visitor(&argit, arge);
+ ArgsVisitor visitor(&argit, arge, env_prefix);
for ( ; argit != arge; ++argit )
{
@@ -144,6 +146,10 @@ ArgsHandler::run(const int argc, const char * const * const argv, const std::str
_imp->parameters.insert(_imp->parameters.end(),
argit, libwrapiter::ForwardIterator<ArgsVisitor, std::string>(args.end()));
+
+ if (! env_prefix.empty())
+ setenv((env_prefix + "_PARAMS").c_str(), join(_imp->parameters.begin(),
+ _imp->parameters.end(), " ").c_str(), 1);
}
void
diff --git a/paludis/args/args_handler.hh b/paludis/args/args_handler.hh
index d685d7e..55ae913 100644
--- a/paludis/args/args_handler.hh
+++ b/paludis/args/args_handler.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -84,11 +84,13 @@ namespace paludis
///\}
/**
- * Parse command line arguments. The last (optional) argument is the name
+ * Parse command line arguments. The third (optional) argument is the name
* of an environment variable holding arguments which are prepended to the
- * command line arguments.
+ * command line arguments. The fourth (optional) argument is used as a prefix
+ * to export our command line via the environment.
*/
- void run(const int, const char * const * const, const std::string & env_var = "");
+ void run(const int, const char * const * const, const std::string & env_var = "",
+ const std::string & env_prefix = "");
///\name Iterate over our parameters (non - and -- switches and their values)
///\{
diff --git a/paludis/args/args_visitor.cc b/paludis/args/args_visitor.cc
index c510f8b..4eb20a4 100644
--- a/paludis/args/args_visitor.cc
+++ b/paludis/args/args_visitor.cc
@@ -1,6 +1,6 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -21,8 +21,12 @@
#include <paludis/util/visitor.hh>
#include <paludis/util/destringify.hh>
+#include <paludis/util/system.hh>
+#include <paludis/util/join.hh>
+#include <algorithm>
#include <sstream>
+#include <stdlib.h>
/** \file
* Implementation for ArgsVisitor.
@@ -34,7 +38,11 @@ using namespace paludis;
using namespace args;
ArgsVisitor::ArgsVisitor(libwrapiter::ForwardIterator<ArgsVisitor, std::string> * ai,
- libwrapiter::ForwardIterator<ArgsVisitor, std::string> ae) : _args_index(ai), _args_end(ae)
+ libwrapiter::ForwardIterator<ArgsVisitor, std::string> ae,
+ const std::string & env_prefix) :
+ _args_index(ai),
+ _args_end(ae),
+ _env_prefix(env_prefix)
{
}
@@ -42,21 +50,27 @@ const std::string &
ArgsVisitor::get_param(const ArgsOption * const arg)
{
if (++(*_args_index) == _args_end)
- {
throw MissingValue("--" + arg->long_name());
- }
+
return **_args_index;
}
void ArgsVisitor::visit(ArgsOption * const arg)
{
arg->set_specified(true);
+
+ if (! _env_prefix.empty())
+ setenv(env_name(arg->long_name()).c_str(), "1", 1);
}
void ArgsVisitor::visit(StringArg * const arg)
{
visit(static_cast<ArgsOption *>(arg));
- arg->set_argument(get_param(arg));
+ std::string p(get_param(arg));
+ arg->set_argument(p);
+
+ if (! _env_prefix.empty())
+ setenv(env_name(arg->long_name()).c_str(), p.c_str(), 1);
}
void ArgsVisitor::visit(AliasArg * const arg)
@@ -75,7 +89,11 @@ void ArgsVisitor::visit(IntegerArg * const arg)
std::string param = get_param(arg);
try
{
- arg->set_argument(destringify<int>(param));
+ int a(destringify<int>(param));
+ arg->set_argument(a);
+
+ if (! _env_prefix.empty())
+ setenv(env_name(arg->long_name()).c_str(), stringify(a).c_str(), 1);
}
catch (const DestringifyError &)
{
@@ -86,7 +104,11 @@ void ArgsVisitor::visit(IntegerArg * const arg)
void ArgsVisitor::visit(EnumArg * const arg)
{
visit(static_cast<ArgsOption*>(arg));
- arg->set_argument(get_param(arg));
+ std::string p(get_param(arg));
+ arg->set_argument(p);
+
+ if (! _env_prefix.empty())
+ setenv(env_name(arg->long_name()).c_str(), p.c_str(), 1);
}
void ArgsVisitor::visit(StringSetArg * const arg)
@@ -94,4 +116,17 @@ void ArgsVisitor::visit(StringSetArg * const arg)
visit(static_cast<ArgsOption *>(arg));
std::string param = get_param(arg);
arg->add_argument(param);
+
+ if (! _env_prefix.empty())
+ setenv(env_name(arg->long_name()).c_str(), join(arg->begin_args(),
+ arg->end_args(), " ").c_str(), 1);
+}
+
+std::string
+ArgsVisitor::env_name(const std::string & long_name) const
+{
+ std::string result(_env_prefix + "_" + long_name);
+ std::replace(result.begin(), result.end(), '-', '_');
+ return result;
}
+
diff --git a/paludis/args/args_visitor.hh b/paludis/args/args_visitor.hh
index 822ae8e..e60769e 100644
--- a/paludis/args/args_visitor.hh
+++ b/paludis/args/args_visitor.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
* Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
*
* This file is part of the Paludis package manager. Paludis is free software;
@@ -63,15 +63,19 @@ namespace paludis
{
private:
libwrapiter::ForwardIterator<ArgsVisitor, std::string> * _args_index, _args_end;
+ std::string _env_prefix;
- const std::string& get_param(const ArgsOption * const);
+ const std::string & get_param(const ArgsOption * const);
+
+ std::string env_name(const std::string & long_name) const;
public:
/**
* Constructor
*/
ArgsVisitor(libwrapiter::ForwardIterator<ArgsVisitor, std::string> *,
- libwrapiter::ForwardIterator<ArgsVisitor, std::string>);
+ libwrapiter::ForwardIterator<ArgsVisitor, std::string>,
+ const std::string & env_prefix = "");
/// Visit an ArgsOption.
void visit(ArgsOption * const);
diff --git a/src/clients/paludis/paludis.cc b/src/clients/paludis/paludis.cc
index 45da942..ea96575 100644
--- a/src/clients/paludis/paludis.cc
+++ b/src/clients/paludis/paludis.cc
@@ -139,7 +139,7 @@ main(int argc, char *argv[])
try
{
- CommandLine::get_instance()->run(argc, argv, "PALUDIS_OPTIONS");
+ CommandLine::get_instance()->run(argc, argv, "PALUDIS_OPTIONS", "PALUDIS_CMDLINE");
set_use_colour(! CommandLine::get_instance()->a_no_color.specified());
if (CommandLine::get_instance()->a_help.specified())