aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-01-02 22:24:38 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-01-02 22:24:38 +0000
commit09fd9de589f9b5edbaa23cc242d28ebc2ae62531 (patch)
tree1551c3a76961847c37a11a7d4c8654efaba7553e
parentd47ccc4a0abc3f87339fdb7d24bcb4b854fdc647 (diff)
downloadpaludis-09fd9de589f9b5edbaa23cc242d28ebc2ae62531.tar.gz
paludis-09fd9de589f9b5edbaa23cc242d28ebc2ae62531.tar.xz
Cleaner output managers
-rw-r--r--.gitignore1
-rw-r--r--configure.ac1
-rw-r--r--paludis/buffer_output_manager-fwd.hh (renamed from paludis/messages_to_stdout_output_handler-fwd.hh)8
-rw-r--r--paludis/buffer_output_manager.cc118
-rw-r--r--paludis/buffer_output_manager.hh (renamed from paludis/messages_to_stdout_output_handler.hh)31
-rw-r--r--paludis/environments/paludis/Makefile.am3
-rw-r--r--paludis/environments/paludis/default_output.conf196
-rw-r--r--paludis/environments/paludis/output_conf.cc274
-rw-r--r--paludis/environments/paludis/output_conf.hh5
-rw-r--r--paludis/environments/paludis/output_managers.cc198
-rw-r--r--paludis/environments/paludis/output_managers.hh76
-rw-r--r--paludis/environments/paludis/output_managers/Makefile.am35
-rw-r--r--paludis/environments/paludis/output_managers/keep_messages.part.conf10
-rw-r--r--paludis/environments/paludis/output_managers/keep_stdout_as_messages.part.conf10
-rw-r--r--paludis/environments/paludis/output_managers/logged.conf6
-rw-r--r--paludis/environments/paludis/output_managers/logged_only.part.conf11
-rw-r--r--paludis/environments/paludis/output_managers/quiet.conf6
-rw-r--r--paludis/environments/paludis/output_managers/show_messages.part.conf5
-rw-r--r--paludis/environments/paludis/output_managers/standard.conf4
-rw-r--r--paludis/environments/paludis/output_managers/standard_on_failure.conf6
-rw-r--r--paludis/environments/paludis/paludis_config.cc49
-rw-r--r--paludis/environments/paludis/paludis_config.hh4
-rw-r--r--paludis/environments/paludis/paludis_environment.cc7
-rw-r--r--paludis/environments/paludis/paludis_environment.hh4
-rw-r--r--paludis/environments/paludis/tests_output.conf12
-rw-r--r--paludis/file_output_manager.cc114
-rw-r--r--paludis/file_output_manager.hh11
-rw-r--r--paludis/files.m43
-rw-r--r--paludis/format_messages_output_manager-fwd.hh28
-rw-r--r--paludis/format_messages_output_manager.cc192
-rw-r--r--paludis/format_messages_output_manager.hh76
-rw-r--r--paludis/forward_on_failure_output_manager.cc10
-rw-r--r--paludis/forward_on_failure_output_manager.hh2
-rw-r--r--paludis/messages_to_stdout_output_handler.cc171
-rw-r--r--paludis/output_manager.hh21
-rw-r--r--paludis/output_manager_factory.cc12
-rw-r--r--paludis/standard_output_manager.cc10
-rw-r--r--paludis/standard_output_manager.hh2
-rw-r--r--paludis/tee_output_manager.cc57
-rw-r--r--paludis/tee_output_manager.hh6
-rw-r--r--paludis/util/executor.cc12
-rw-r--r--paludis/util/executor.hh1
-rw-r--r--src/clients/cave/cmd_sync.cc31
-rw-r--r--src/clients/cave/formats.cc4
44 files changed, 1053 insertions, 790 deletions
diff --git a/.gitignore b/.gitignore
index f0ed794..f8c4d4d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -373,6 +373,7 @@ paludis-*.*.*.tar.bz2
/paludis/util/Makefile.am
/paludis/util/action_queue_TEST
/paludis/util/active_object_ptr_TEST
+/paludis/util/buffer_output_stream_TEST
/paludis/util/byte_swap_TEST
/paludis/util/condition_variable_TEST
/paludis/util/config_file_TEST
diff --git a/configure.ac b/configure.ac
index 27beb4b..15ded82 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1594,7 +1594,6 @@ AC_OUTPUT(
paludis/environments/Makefile
paludis/environments/no_config/Makefile
paludis/environments/paludis/Makefile
- paludis/environments/paludis/output_managers/Makefile
paludis/environments/portage/Makefile
paludis/environments/test/Makefile
paludis/fetchers/Makefile
diff --git a/paludis/messages_to_stdout_output_handler-fwd.hh b/paludis/buffer_output_manager-fwd.hh
index 9e2ec56..270f97a 100644
--- a/paludis/messages_to_stdout_output_handler-fwd.hh
+++ b/paludis/buffer_output_manager-fwd.hh
@@ -17,12 +17,14 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_MESSAGES_TO_STDOUT_OUTPUT_HANDLER_FWD_HH
-#define PALUDIS_GUARD_PALUDIS_MESSAGES_TO_STDOUT_OUTPUT_HANDLER_FWD_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_BUFFER_OUTPUT_MANAGER_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_BUFFER_OUTPUT_MANAGER_FWD_HH 1
+
+#include <paludis/output_manager-fwd.hh>
namespace paludis
{
- struct MessagesToStdoutOutputManager;
+ class BufferOutputManager;
}
#endif
diff --git a/paludis/buffer_output_manager.cc b/paludis/buffer_output_manager.cc
new file mode 100644
index 0000000..27808c3
--- /dev/null
+++ b/paludis/buffer_output_manager.cc
@@ -0,0 +1,118 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Ciaran McCreesh
+ *
+ * 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/buffer_output_manager.hh>
+#include <paludis/util/buffer_output_stream.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/set.hh>
+#include <paludis/util/exception.hh>
+
+using namespace paludis;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<BufferOutputManager>
+ {
+ const std::tr1::shared_ptr<OutputManager> child;
+ BufferOutputStream stdout_stream;
+ BufferOutputStream stderr_stream;
+
+ Implementation(
+ const std::tr1::shared_ptr<OutputManager> & c) :
+ child(c)
+ {
+ }
+ };
+}
+
+BufferOutputManager::BufferOutputManager(
+ const std::tr1::shared_ptr<OutputManager> & c) :
+ PrivateImplementationPattern<BufferOutputManager>(new Implementation<BufferOutputManager>(c))
+{
+}
+
+BufferOutputManager::~BufferOutputManager()
+{
+ flush();
+}
+
+std::ostream &
+BufferOutputManager::stdout_stream()
+{
+ return _imp->stdout_stream;
+}
+
+std::ostream &
+BufferOutputManager::stderr_stream()
+{
+ return _imp->stderr_stream;
+}
+
+void
+BufferOutputManager::succeeded()
+{
+ _imp->child->succeeded();
+}
+
+void
+BufferOutputManager::message(const MessageType, const std::string &)
+{
+}
+
+void
+BufferOutputManager::flush()
+{
+ _imp->stdout_stream.unbuffer(_imp->child->stdout_stream());
+ _imp->stderr_stream.unbuffer(_imp->child->stderr_stream());
+ _imp->child->flush();
+}
+
+void
+BufferOutputManager::nothing_more_to_come()
+{
+ _imp->child->nothing_more_to_come();
+}
+
+const std::tr1::shared_ptr<const Set<std::string> >
+BufferOutputManager::factory_managers()
+{
+ std::tr1::shared_ptr<Set<std::string> > result(new Set<std::string>);
+ result->insert("buffer");
+ return result;
+}
+
+const std::tr1::shared_ptr<OutputManager>
+BufferOutputManager::factory_create(
+ const OutputManagerFactory::KeyFunction & key_func,
+ const OutputManagerFactory::CreateChildFunction & create_child,
+ const OutputManagerFactory::ReplaceVarsFunc &)
+{
+ std::string child_str(key_func("child"));
+ if (child_str.empty())
+ throw ConfigurationError("No child specified for BufferOutputManager");
+ const std::tr1::shared_ptr<OutputManager> child(create_child(child_str));
+
+ return make_shared_ptr(new BufferOutputManager(child));
+}
+
+template class PrivateImplementationPattern<BufferOutputManager>;
+
diff --git a/paludis/messages_to_stdout_output_handler.hh b/paludis/buffer_output_manager.hh
index 5591931..4f079dc 100644
--- a/paludis/messages_to_stdout_output_handler.hh
+++ b/paludis/buffer_output_manager.hh
@@ -17,40 +17,34 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_MESSAGES_TO_STDOUT_OUTPUT_HANDLER_HH
-#define PALUDIS_GUARD_PALUDIS_MESSAGES_TO_STDOUT_OUTPUT_HANDLER_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_BUFFER_OUTPUT_MANAGER_HH
+#define PALUDIS_GUARD_PALUDIS_BUFFER_OUTPUT_MANAGER_HH 1
-#include <paludis/messages_to_stdout_output_handler-fwd.hh>
+#include <paludis/tee_output_manager-fwd.hh>
#include <paludis/output_manager.hh>
#include <paludis/output_manager_factory.hh>
-#include <paludis/util/set-fwd.hh>
#include <paludis/util/private_implementation_pattern.hh>
-#include <paludis/util/fs_entry-fwd.hh>
#include <tr1/memory>
#include <tr1/functional>
namespace paludis
{
- class PALUDIS_VISIBLE MessagesToStdoutOutputManager :
- private PrivateImplementationPattern<MessagesToStdoutOutputManager>,
+ class PALUDIS_VISIBLE BufferOutputManager :
+ private PrivateImplementationPattern<BufferOutputManager>,
public OutputManager
{
public:
- MessagesToStdoutOutputManager(
- const std::tr1::shared_ptr<OutputManager> &,
- const OutputManagerFactory::ReplaceVarsFunc &,
- const std::string & f_debug,
- const std::string & f_info,
- const std::string & f_warn,
- const std::string & f_error,
- const std::string & f_log);
-
- ~MessagesToStdoutOutputManager();
+ BufferOutputManager(
+ const std::tr1::shared_ptr<OutputManager> &
+ );
+ ~BufferOutputManager();
virtual std::ostream & stdout_stream() PALUDIS_ATTRIBUTE((warn_unused_result));
virtual std::ostream & stderr_stream() PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void succeeded();
+ virtual void flush();
+ virtual void nothing_more_to_come();
virtual void message(const MessageType, const std::string &);
static const std::tr1::shared_ptr<const Set<std::string> > factory_managers()
@@ -64,8 +58,9 @@ namespace paludis
};
#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
- extern template class PrivateImplementationPattern<MessagesToStdoutOutputManager>;
+ extern template class PrivateImplementationPattern<BufferOutputManager>;
#endif
}
+
#endif
diff --git a/paludis/environments/paludis/Makefile.am b/paludis/environments/paludis/Makefile.am
index e0e46e7..c32a939 100644
--- a/paludis/environments/paludis/Makefile.am
+++ b/paludis/environments/paludis/Makefile.am
@@ -1,6 +1,6 @@
include $(top_srcdir)/misc/common-makefile.am
-SUBDIRS = output_managers .
+SUBDIRS = .
AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
DEFS= \
-DSYSCONFDIR=\"$(sysconfdir)\" \
@@ -18,7 +18,6 @@ libpaludispaludisenvironment_la_SOURCES = \
use_conf.cc use_conf.hh \
mirrors_conf.cc mirrors_conf.hh \
output_conf.cc output_conf.hh \
- output_managers.cc output_managers.hh \
world.cc world.hh \
paludis_config.cc paludis_config.hh \
paludis_environment.cc paludis_environment.hh \
diff --git a/paludis/environments/paludis/default_output.conf b/paludis/environments/paludis/default_output.conf
index 863880e..906175c 100644
--- a/paludis/environments/paludis/default_output.conf
+++ b/paludis/environments/paludis/default_output.conf
@@ -1,19 +1,193 @@
-# By default, output to stdout, keep logs of messages and keep output logs on
-# failure:
+# vim: set tw=80 ft=conf et sw=4 sts=4 :
-type = * : logged
+# This is the default output configuration. In general, we show output to stdout
+# where possible, we keep logs of messages, and we keep logs of output only if a
+# failure occurs.
+#
+# We use a few user-settable variables:
+#
+# always_keep_output_logs may be set to 'true' to always keep output logs, even
+# if a build succeeds.
+#
+# quiet may be set to 'true' to show only messages, rather than all output, when
+# carrying out an action.
-# But if we're being run in the background, display only messages to stdout, and
-# keep logs of messages and keep output logs on failure:
+# First, we define some basic rules. If we're running exclusively, use the
+# 'exclusive' manager:
+[rule default_exclusive]
+type = *
+output_exclusivity = exclusive
+manager = exclusive
-type = * output_exclusivity = background : quiet
+# If we're running with others, use the 'interleaved' manager:
+[rule default_interleaved]
+type = *
+output_exclusivity = with_others
+manager = interleaved
-# We don't want to log pretend actions though. They're often run as a normal
-# user, and keeping logs isn't useful.
+# And if we're running in the background, use the 'background' manager:
+[rule default_background]
+type = *
+output_exclusivity = background
+manager = background
-type = package action = pretend : standard
+# We want special handling for pretends. Logging them is generally a bad idea,
+# since it often prevents running as a normal user, and it's a waste of space,
+# so we go straight to 'standard'. This generally shouldn't be overridden.
+[rule default_pretend]
+type = package
+action = pretend
+output_exclusivity = exclusive
+manager = standard
-# We only want to show pretend-time fetch verification if it failed.
+# For pretend-fetches, we don't want to display any output at all, except if
+# something fails, so we go to 'standard_on_failure'. Again, this generally
+# shouldn't be overridden:
+[rule default_pretend_fetch]
+type = package
+action = fetch
+ignore_unfetched = true
+output_exclusivity = exclusive
+manager = standard_on_failure
-type = package action = fetch ignore_unfetched = true : standard_on_failure
+# Next, our output managers. The simplest goes straight to stdout / stderr:
+[manager standard]
+handler = standard
+
+# For when we want to send output to stdout / stderr, but only if things failed:
+[manager standard_on_failure]
+handler = forward_on_failure
+child = standard
+
+# For when we're running with other processes, we send output to stdout /
+# stderr, but only when we're told to do so, to avoid mixing up outputs from
+# different processes in a huge confusing mess:
+[manager standard_interleaved]
+handler = buffer
+child = standard
+
+# The 'log_output' manager forwards to 'log_output_keep_always', unless the user
+# has set 'always_keep_output_logs' to 'true', in which case it goes to
+# 'log_output_keep_failures'.
+[manager log_output]
+handler = conditional_alias
+condition_variable = always_keep_output_logs
+if_true = log_output_keep_always
+if_false = log_output_keep_failures
+if_unset = log_output_keep_failures
+
+# Our output log goes to a file, which gets discarded if we succeed or if it's
+# empty. The summary_output options are used to display a message showing the
+# location of the log when our output manager is closed:
+[manager log_output_keep_failures]
+handler = file
+filename = ${root}/var/log/paludis/%{time}-%{action}-%{full_name}.out
+keep_on_empty = false
+keep_on_success = false
+summary_output_manager = format_messages_standard
+summary_output_message = Output log: ${filename}
+
+# A variant on log_output_keep_failures, that always keeps logs. Selected if
+# 'always_keep_output_logs' is 'true'.
+[manager log_output_keep_always]
+handler = file
+filename = ${root}/var/log/paludis/%{time}-%{action}-%{full_name}.out
+keep_on_empty = false
+keep_on_success = true
+summary_output_manager = format_messages_standard
+summary_output_message = Output log: ${filename}
+
+# For messages from background and quiet processes, we format them, and then
+# send them to standard output when we're told to do so:
+[manager format_messages_interleaved]
+handler = format_messages
+format_debug =
+format_info = "%{green}***%{normal} %{message}%{newline}"
+format_warn = "%{yellow}***%{normal} %{message}%{newline}"
+format_error = "%{red}***%{normal} %{message}%{newline}"
+format_log = "%{blue}***%{normal} %{message}%{newline}"
+child = standard_interleaved
+
+# For messages from quiet exclusive processes, we format them, and send them to
+# standard output immediately:
+[manager format_messages_standard]
+handler = format_messages
+format_debug =
+format_info = "%{green}***%{normal} %{message}%{newline}"
+format_warn = "%{yellow}***%{normal} %{message}%{newline}"
+format_error = "%{red}***%{normal} %{message}%{newline}"
+format_log = "%{blue}***%{normal} %{message}%{newline}"
+child = standard
+
+# For messages going to logs, we format without colour:
+[manager format_log_messages_always]
+handler = format_messages
+format_debug =
+format_info = I %{message}%{newline}
+format_warn = W %{message}%{newline}
+format_error = E %{message}%{newline}
+format_log = L %{message}%{newline}
+child = log_messages_always
+
+# Our messages log goes to a file, which gets discarded only if it is empty:
+[manager log_messages_always]
+handler = file
+filename = ${root}/var/log/paludis/${time}-%{action}-%{full_name}.messages
+keep_on_empty = false
+keep_on_success = true
+summary_output_manager = format_messages_standard
+summary_output_message = Messages log: ${filename}
+
+# Our handler for 'exclusive' forwards to either 'exclusive_default', or, if
+# 'quiet' is set to 'true', 'exclusive_quiet'.
+[manager exclusive]
+handler = conditional_alias
+condition_variable = quiet
+if_true = exclusive_quiet
+if_false = exclusive_default
+if_unset = exclusive_default
+
+# When we're running exclusively, send output to standard, keep an output log
+# which, at user option, is deleted upon success, and keep a messages log:
+[manager exclusive_default]
+handler = tee
+children = standard log_output
+messages = format_log_messages_always
+
+# Alternatively, only send messages to standard rather than full output:
+[manager exclusive_quiet]
+handler = tee
+children = log_output
+messages = format_log_messages_always format_messages
+
+# Our handler for 'interleaved' forwards to either 'interleaved_default' or, if
+# 'quiet' is set to 'true', 'interleaved_quiet':
+[manager interleaved]
+handler = conditional_alias
+condition_variable = quiet
+if_true = interleaved_quiet
+if_false = interleaved_default
+if_unset = interleaved_default
+
+# When we're running with other processes, send output to standard only when
+# told to, keep an output which, at user option, is deleted upon success, and
+# keep a messages log:
+[manager interleaved_default]
+handler = tee
+children = standard_interleaved log_output
+messages = format_log_messages_always
+
+# Alternatively, only send messages to standard rather than full output:
+[manager interleaved_quiet]
+handler = tee
+children = log_output
+messages = format_log_messages_always format_messages_interleaved
+
+# When we're running in the background, keep an output log which, at user
+# option, is deleted upon success, always keep a messages log, and send messages
+# to standard only when told to:
+[manager background]
+handler = tee
+children = log_output
+messages = format_log_messages_always format_messages_interleaved
diff --git a/paludis/environments/paludis/output_conf.cc b/paludis/environments/paludis/output_conf.cc
index 826ed4a..29cce1d 100644
--- a/paludis/environments/paludis/output_conf.cc
+++ b/paludis/environments/paludis/output_conf.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * Copyright (c) 2009, 2010 Ciaran McCreesh
*
* 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
@@ -34,13 +34,19 @@
#include <paludis/util/make_shared_copy.hh>
#include <paludis/util/tribool.hh>
#include <paludis/util/simple_visitor_cast.hh>
+#include <paludis/util/map.hh>
+#include <paludis/util/simple_parser.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/create_output_manager_info.hh>
#include <paludis/package_id.hh>
#include <paludis/match_package.hh>
#include <paludis/action.hh>
+#include <paludis/output_manager_factory.hh>
+#include <paludis/metadata_key.hh>
#include <list>
#include <vector>
+#include <map>
+#include <algorithm>
using namespace paludis;
using namespace paludis::paludis_environment;
@@ -73,6 +79,17 @@ namespace
};
typedef std::list<Rule> RuleList;
+ typedef std::map<std::string, std::tr1::shared_ptr<Map<std::string, std::string> > > Managers;
+
+ std::string from_keys(
+ const std::tr1::shared_ptr<const Map<std::string, std::string> > & m,
+ const std::string & k)
+ {
+ if (m->end() == m->find(k))
+ return "";
+ else
+ return m->find(k)->second;
+ }
}
namespace paludis
@@ -82,6 +99,8 @@ namespace paludis
{
const PaludisEnvironment * const env;
RuleList rules;
+ Managers managers;
+ std::map<std::string, std::string> misc_vars;
Implementation(const PaludisEnvironment * const e) :
env(e)
@@ -116,6 +135,8 @@ namespace
rule.action_requirement() = v;
else if (k == "ignore_unfetched")
rule.ignore_unfetched_requirement() = destringify<Tribool>(v);
+ else if (k == "manager")
+ rule.manager() = v;
else
throw PaludisConfigError("Unknown rule '" + k + "'");
}
@@ -192,6 +213,100 @@ namespace
MatchRuleVisitor v(e, rule);
return i.accept_returning<bool>(v);
}
+
+ std::string escape(const std::string & s)
+ {
+ std::string result(s);
+ std::replace(result.begin(), result.end(), ' ', '_');
+ std::replace(result.begin(), result.end(), '/', '_');
+ return result;
+ }
+
+ struct CreateVarsFromInfo
+ {
+ std::tr1::shared_ptr<Map<std::string, std::string> > m;
+
+ CreateVarsFromInfo(std::tr1::shared_ptr<Map<std::string, std::string> > & mm) :
+ m(mm)
+ {
+ /* convenience, for everyone */
+ m->insert("newline", "\n");
+ m->insert("red", "\033[1;31m");
+ m->insert("yellow", "\033[1;33m");
+ m->insert("green", "\033[1;32m");
+ m->insert("blue", "\033[1;34m");
+ m->insert("normal", "\033[0;0m");
+ m->insert("time", stringify(time(0)));
+ m->insert("pid", stringify(getpid()));
+ }
+
+ void visit(const CreateOutputManagerForRepositorySyncInfo & i)
+ {
+ m->insert("type", "repository");
+ m->insert("action", "sync");
+ m->insert("name", stringify(i.repository().name()));
+ m->insert("full_name", stringify(i.repository().name()));
+ }
+
+ void visit(const CreateOutputManagerForPackageIDActionInfo & i)
+ {
+ m->insert("type", "package");
+ m->insert("action", action_to_string(i.action()));
+ m->insert("name", stringify(i.package_id()->name()));
+ m->insert("id", escape(stringify(*i.package_id())));
+ m->insert("full_name", escape(stringify(*i.package_id())));
+ if (i.package_id()->slot_key())
+ m->insert("slot", stringify(i.package_id()->slot_key()->value()));
+ m->insert("version", stringify(i.package_id()->version()));
+ m->insert("repository", stringify(i.package_id()->repository()->name()));
+ m->insert("category", stringify(i.package_id()->name().category()));
+ m->insert("package", stringify(i.package_id()->name().package()));
+ }
+ };
+
+ const std::tr1::shared_ptr<Map<std::string, std::string> >
+ vars_from_create_output_manager_info(const CreateOutputManagerInfo & i)
+ {
+ std::tr1::shared_ptr<Map<std::string, std::string> > result(new Map<std::string, std::string>);
+ CreateVarsFromInfo v(result);
+ i.accept(v);
+ return result;
+ }
+
+ const std::string replace_percent_vars(
+ const std::string & s,
+ const std::tr1::shared_ptr<const Map<std::string, std::string> > & vars,
+ const std::tr1::shared_ptr<const Map<std::string, std::string> > & override_vars,
+ const std::tr1::shared_ptr<const Map<std::string, std::string> > & file_vars)
+ {
+ std::string result, token;
+ SimpleParser parser(s);
+ while (! parser.eof())
+ {
+ if (parser.consume((+simple_parser::any_except("%")) >> token))
+ result.append(token);
+ else if (parser.consume(simple_parser::exact("%%")))
+ result.append("%");
+ else if (parser.consume(simple_parser::exact("%{") &
+ ((+simple_parser::any_except("} \t\r\n%")) >> token) &
+ simple_parser::exact("}")))
+ {
+ Map<std::string, std::string>::ConstIterator v(override_vars->find(token));
+ if (v == override_vars->end())
+ v = vars->find(token);
+ if (v == vars->end())
+ v = file_vars->find(token);
+ if (v == file_vars->end())
+ throw PaludisConfigError("No variable named '" + token + "' in var string '" + s + "'");
+
+ result.append(v->second);
+ }
+ else
+ throw PaludisConfigError("Invalid var string '" + s + "'");
+ }
+
+ return result;
+ }
}
void
@@ -199,28 +314,55 @@ OutputConf::add(const FSEntry & filename)
{
Context context("When adding source '" + stringify(filename) + "' as an output file:");
- std::tr1::shared_ptr<LineConfigFile> f(make_bashable_conf(filename, LineConfigFileOptions()));
+ std::tr1::shared_ptr<KeyValueConfigFile> f(make_bashable_kv_conf(filename,
+ make_shared_ptr(new Map<std::string, std::string>),
+ KeyValueConfigFileOptions() + kvcfo_allow_sections));
if (! f)
return;
- for (LineConfigFile::ConstIterator line(f->begin()), line_end(f->end()) ;
- line != line_end ; ++line)
- {
- std::vector<std::string> tokens;
- tokenise_whitespace_quoted(*line, std::back_inserter(tokens));
+ Managers local_managers, local_rules;
- if (tokens.empty())
+ for (KeyValueConfigFile::ConstIterator k(f->begin()), k_end(f->end()) ;
+ k != k_end ; ++k)
+ {
+ std::string remainder(k->first);
+ std::string::size_type p(remainder.find('/'));
+ if (std::string::npos == p)
+ {
+ _imp->misc_vars[k->first] = k->second;
continue;
+ }
- if ("source" == tokens.at(0))
- {
- if (tokens.size() != 2)
- throw PaludisConfigError("Invalid source line '" + *line + "'");
+ std::string section_kind(remainder.substr(0, p));
+ remainder.erase(0, p + 1);
- add(FSEntry(tokens.at(1)));
- continue;
+ p = remainder.find('/');
+ if (std::string::npos == p)
+ throw PaludisConfigError("Section '" + section_kind + "' has no name");
+ std::string section_name(remainder.substr(0, p));
+ remainder.erase(0, p + 1);
+
+ if (section_kind == "rule")
+ {
+ local_rules.insert(
+ std::make_pair(section_name,
+ make_shared_ptr(new Map<std::string, std::string>))).first->second->insert(
+ remainder, k->second);
}
+ else if (section_kind == "manager")
+ {
+ local_managers.insert(
+ std::make_pair(section_name,
+ make_shared_ptr(new Map<std::string, std::string>))).first->second->insert(
+ remainder, k->second);
+ }
+ else
+ throw PaludisConfigError("Section kind '" + section_kind + "' unknown");
+ }
+ for (Managers::const_iterator r(local_rules.begin()), r_end(local_rules.end()) ;
+ r != r_end ; ++r)
+ {
Rule rule(make_named_values<Rule>(
value_for<n::action_requirement>("*"),
value_for<n::ignore_unfetched_requirement>(indeterminate),
@@ -230,45 +372,16 @@ OutputConf::add(const FSEntry & filename)
value_for<n::output_exclusivity_requirement>(static_cast<OutputExclusivity>(-1)),
value_for<n::type_requirement>("*")
));
+ for (Map<std::string, std::string>::ConstIterator m(r->second->begin()), m_end(r->second->end()) ;
+ m != m_end ; ++m)
+ set_rule(_imp->env, rule, m->first, m->second);
- std::vector<std::string>::const_iterator t(tokens.begin()), t_end(tokens.end());
-
- for ( ; t != t_end ; ++t)
- {
- if (*t == ":")
- break;
-
- std::string::size_type p(t->find("="));
- if (std::string::npos != p)
- set_rule(_imp->env, rule, t->substr(0, p), t->substr(p + 1));
- else
- {
- std::string r(*t);
- if (++t == t_end)
- throw PaludisConfigError("Expected '=' but found end of line for line '" + *line + "'");
-
- if (*t != "=")
- throw PaludisConfigError("Expected '=' but found '" + *t + "' for line '" + *line + "'");
-
- if (++t == t_end)
- throw PaludisConfigError("Expected value but found end of for line '" + *line + "'");
-
- set_rule(_imp->env, rule, r, *t);
- }
- }
-
- if (t == t_end)
- throw PaludisConfigError("Found no ':' for line '" + *line + "'");
-
- if (++t == t_end)
- throw PaludisConfigError("Found no manager after ':' for line '" + *line + "'");
-
- rule.manager() = *t;
_imp->rules.push_back(rule);
-
- if (++t != t_end)
- throw PaludisConfigError("Trailing text after manager on line '" + *line + "'");
}
+
+ for (Managers::const_iterator m(local_managers.begin()), m_end(local_managers.end()) ;
+ m != m_end ; ++m)
+ _imp->managers[m->first] = m->second;
}
const std::tr1::shared_ptr<OutputManager>
@@ -279,10 +392,69 @@ OutputConf::create_output_manager(const CreateOutputManagerInfo & i) const
for (RuleList::const_reverse_iterator r(_imp->rules.rbegin()), r_end(_imp->rules.rend()) ;
r != r_end ; ++r)
if (match_rule(_imp->env, *r, i))
- return _imp->env->create_named_output_manager(r->manager(), i);
+ return create_named_output_manager(r->manager(), i);
throw PaludisConfigError("No matching output manager rule specified");
}
+const std::tr1::shared_ptr<OutputManager>
+OutputConf::create_named_output_manager(const std::string & s, const CreateOutputManagerInfo & n) const
+{
+ Context context("When creating output manager named '" + s + "':");
+
+ Managers::const_iterator i(_imp->managers.find(s));
+ if (i == _imp->managers.end())
+ throw PaludisConfigError("No output manager named '" + s + "' exists");
+
+ std::tr1::shared_ptr<Map<std::string, std::string> > vars(vars_from_create_output_manager_info(n));
+
+ std::string handler;
+ if (i->second->end() != i->second->find("handler"))
+ handler = i->second->find("handler")->second;
+
+ if (handler == "conditional_alias")
+ {
+ /* easier to handle this specially here */
+ std::string condition_variable;
+ if (i->second->end() != i->second->find("condition_variable"))
+ condition_variable = i->second->find("condition_variable")->second;
+
+ if (condition_variable.empty())
+ throw PaludisConfigError("No condition_variable specified for manager '" + s + "'");
+
+ std::string value;
+ if (_imp->misc_vars.end() != _imp->misc_vars.find(condition_variable))
+ value = _imp->misc_vars.find(condition_variable)->second;
+
+ std::string alias_var;
+ if (value.empty())
+ alias_var = "if_unset";
+ else if (value == "true")
+ alias_var = "if_true";
+ else if (value == "false")
+ alias_var = "if_false";
+ else
+ throw PaludisConfigError("For manager '" + s + "', condition_variable '" + condition_variable
+ + "' should be either 'true', 'false' or unset, but is instead '" + alias_var + "'");
+
+ std::string alias;
+ if (i->second->end() != i->second->find(alias_var))
+ alias = i->second->find(alias_var)->second;
+
+ if (alias.empty())
+ throw PaludisConfigError("For manager '" + s + "', no alias is defined");
+
+ return create_named_output_manager(alias, n);
+ }
+ else
+ return OutputManagerFactory::get_instance()->create(
+ std::tr1::bind(&from_keys, i->second, std::tr1::placeholders::_1),
+ std::tr1::bind(&OutputConf::create_named_output_manager, this,
+ std::tr1::placeholders::_1, std::tr1::cref(n)),
+ std::tr1::bind(replace_percent_vars, std::tr1::placeholders::_1, vars, std::tr1::placeholders::_2,
+ i->second)
+ );
+}
+
template class PrivateImplementationPattern<paludis_environment::OutputConf>;
diff --git a/paludis/environments/paludis/output_conf.hh b/paludis/environments/paludis/output_conf.hh
index 903b03c..1edbb3b 100644
--- a/paludis/environments/paludis/output_conf.hh
+++ b/paludis/environments/paludis/output_conf.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * Copyright (c) 2009, 2010 Ciaran McCreesh
*
* 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
@@ -53,6 +53,9 @@ namespace paludis
const std::tr1::shared_ptr<OutputManager> create_output_manager(
const CreateOutputManagerInfo &) const;
+
+ const std::tr1::shared_ptr<OutputManager> create_named_output_manager(
+ const std::string & s, const CreateOutputManagerInfo & n) const;
};
}
diff --git a/paludis/environments/paludis/output_managers.cc b/paludis/environments/paludis/output_managers.cc
deleted file mode 100644
index 24ed027..0000000
--- a/paludis/environments/paludis/output_managers.cc
+++ /dev/null
@@ -1,198 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2009 Ciaran McCreesh
- *
- * 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
- * Public License version 2, as published by the Free Software Foundation.
- *
- * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <paludis/environments/paludis/output_managers.hh>
-#include <paludis/environments/paludis/bashable_conf.hh>
-#include <paludis/environments/paludis/paludis_config.hh>
-#include <paludis/environments/paludis/paludis_environment.hh>
-#include <paludis/environments/paludis/action_to_string.hh>
-#include <paludis/util/private_implementation_pattern-impl.hh>
-#include <paludis/util/config_file.hh>
-#include <paludis/util/wrapped_forward_iterator.hh>
-#include <paludis/util/map.hh>
-#include <paludis/util/strip.hh>
-#include <paludis/util/simple_parser.hh>
-#include <paludis/output_manager_factory.hh>
-#include <paludis/create_output_manager_info.hh>
-#include <paludis/package_id.hh>
-#include <paludis/metadata_key.hh>
-#include <algorithm>
-#include <tr1/unordered_map>
-#include <sys/types.h>
-#include <unistd.h>
-#include <time.h>
-
-using namespace paludis;
-using namespace paludis::paludis_environment;
-
-namespace
-{
- typedef std::tr1::unordered_map<std::string, std::tr1::shared_ptr<const KeyValueConfigFile> > Store;
-
- std::string from_kv(const std::tr1::shared_ptr<const KeyValueConfigFile> & m,
- const std::string & k)
- {
- return m->get(k);
- }
-}
-
-namespace paludis
-{
- template<>
- struct Implementation<OutputManagers>
- {
- Store store;
- };
-}
-
-OutputManagers::OutputManagers(const PaludisEnvironment * const) :
- PrivateImplementationPattern<OutputManagers>(new Implementation<OutputManagers>)
-{
-}
-
-OutputManagers::~OutputManagers()
-{
-}
-
-void
-OutputManagers::add(const FSEntry & filename, const std::tr1::shared_ptr<const Map<std::string, std::string> > & predefined_variables)
-{
- Context context("When adding source '" + stringify(filename) + "' as an output manager file:");
-
- std::tr1::shared_ptr<KeyValueConfigFile> f(make_bashable_kv_conf(filename, predefined_variables, KeyValueConfigFileOptions()));
- if (! f)
- return;
-
- std::string manager(filename.basename());
- manager = strip_trailing_string(manager, ".conf");
- manager = strip_trailing_string(manager, ".bash");
-
- _imp->store[manager] = f;
-}
-
-const std::tr1::shared_ptr<OutputManager>
-OutputManagers::create_named_output_manager(const std::string & s, const CreateOutputManagerInfo & n) const
-{
- Context context("When creating output manager named '" + s + "':");
-
- Store::const_iterator i(_imp->store.find(s));
- if (i == _imp->store.end())
- throw PaludisConfigError("No output manager named '" + s + "' exists");
-
- std::tr1::shared_ptr<Map<std::string, std::string> > vars(vars_from_create_output_manager_info(n));
- return OutputManagerFactory::get_instance()->create(
- std::tr1::bind(&from_kv, i->second, std::tr1::placeholders::_1),
- std::tr1::bind(&OutputManagers::create_named_output_manager, this, std::tr1::placeholders::_1, std::tr1::cref(n)),
- std::tr1::bind(replace_percent_vars, std::tr1::placeholders::_1, vars, std::tr1::placeholders::_2)
- );
-}
-
-namespace
-{
- std::string escape(const std::string & s)
- {
- std::string result(s);
- std::replace(result.begin(), result.end(), ' ', '_');
- std::replace(result.begin(), result.end(), '/', '_');
- return result;
- }
-
- struct CreateVarsFromInfo
- {
- std::tr1::shared_ptr<Map<std::string, std::string> > m;
-
- CreateVarsFromInfo(std::tr1::shared_ptr<Map<std::string, std::string> > & mm) :
- m(mm)
- {
- }
-
- void visit(const CreateOutputManagerForRepositorySyncInfo & i)
- {
- m->insert("type", "repository");
- m->insert("action", "sync");
- m->insert("name", stringify(i.repository().name()));
- m->insert("full_name", stringify(i.repository().name()));
- m->insert("pid", stringify(getpid()));
- m->insert("time", stringify(time(0)));
- }
-
- void visit(const CreateOutputManagerForPackageIDActionInfo & i)
- {
- m->insert("type", "package");
- m->insert("action", action_to_string(i.action()));
- m->insert("name", stringify(i.package_id()->name()));
- m->insert("id", escape(stringify(*i.package_id())));
- m->insert("full_name", escape(stringify(*i.package_id())));
- if (i.package_id()->slot_key())
- m->insert("slot", stringify(i.package_id()->slot_key()->value()));
- m->insert("version", stringify(i.package_id()->version()));
- m->insert("repository", stringify(i.package_id()->repository()->name()));
- m->insert("category", stringify(i.package_id()->name().category()));
- m->insert("package", stringify(i.package_id()->name().package()));
- m->insert("pid", stringify(getpid()));
- m->insert("time", stringify(time(0)));
- }
- };
-}
-
-const std::tr1::shared_ptr<Map<std::string, std::string> >
-OutputManagers::vars_from_create_output_manager_info(
- const CreateOutputManagerInfo & i) const
-{
- std::tr1::shared_ptr<Map<std::string, std::string> > result(new Map<std::string, std::string>);
- CreateVarsFromInfo v(result);
- i.accept(v);
- return result;
-}
-
-const std::string
-paludis::paludis_environment::replace_percent_vars(
- const std::string & s,
- const std::tr1::shared_ptr<const Map<std::string, std::string> > & vars,
- const std::tr1::shared_ptr<const Map<std::string, std::string> > & override_vars)
-{
- std::string result, token;
- SimpleParser parser(s);
- while (! parser.eof())
- {
- if (parser.consume((+simple_parser::any_except("%")) >> token))
- result.append(token);
- else if (parser.consume(simple_parser::exact("%%")))
- result.append("%");
- else if (parser.consume(simple_parser::exact("%{") &
- ((+simple_parser::any_except("} \t\r\n%")) >> token) &
- simple_parser::exact("}")))
- {
- Map<std::string, std::string>::ConstIterator v(override_vars->find(token));
- if (v == override_vars->end())
- v = vars->find(token);
- if (v == vars->end())
- throw PaludisConfigError("No variable named '" + token + "' in var string '" + s + "'");
-
- result.append(v->second);
- }
- else
- throw PaludisConfigError("Invalid var string '" + s + "'");
- }
-
- return result;
-}
-
-template class PrivateImplementationPattern<paludis_environment::OutputManagers>;
-
diff --git a/paludis/environments/paludis/output_managers.hh b/paludis/environments/paludis/output_managers.hh
deleted file mode 100644
index 2c51480..0000000
--- a/paludis/environments/paludis/output_managers.hh
+++ /dev/null
@@ -1,76 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2009 Ciaran McCreesh
- *
- * 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
- * Public License version 2, as published by the Free Software Foundation.
- *
- * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef PALUDIS_GUARD_PALUDIS_ENVIRONMENTS_PALUDIS_OUTPUT_MANAGERS_HH
-#define PALUDIS_GUARD_PALUDIS_ENVIRONMENTS_PALUDIS_OUTPUT_MANAGERS_HH 1
-
-#include <paludis/util/attributes.hh>
-#include <paludis/util/private_implementation_pattern.hh>
-#include <paludis/util/instantiation_policy.hh>
-#include <paludis/util/fs_entry-fwd.hh>
-#include <paludis/util/map-fwd.hh>
-#include <paludis/output_manager-fwd.hh>
-#include <paludis/create_output_manager_info-fwd.hh>
-#include <tr1/memory>
-#include <string>
-
-namespace paludis
-{
- class PaludisEnvironment;
-
- namespace paludis_environment
- {
- const std::string replace_percent_vars(
- const std::string &,
- const std::tr1::shared_ptr<const Map<std::string, std::string> > & vars,
- const std::tr1::shared_ptr<const Map<std::string, std::string> > & override_vars);
-
- class OutputManagers :
- private PrivateImplementationPattern<OutputManagers>,
- private InstantiationPolicy<OutputManagers, instantiation_method::NonCopyableTag>
- {
- public:
- ///\name Basic operations
- ///\{
-
- OutputManagers(const PaludisEnvironment * const);
- ~OutputManagers();
-
- ///\}
-
- /**
- * Add another file.
- */
- void add(const FSEntry &, const std::tr1::shared_ptr<const Map<std::string, std::string> > &);
-
- const std::tr1::shared_ptr<OutputManager> create_named_output_manager(
- const std::string &,
- const CreateOutputManagerInfo &) const;
-
- const std::tr1::shared_ptr<Map<std::string, std::string> > vars_from_create_output_manager_info(
- const CreateOutputManagerInfo &) const;
- };
- }
-
-#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
- extern template class PrivateImplementationPattern<paludis_environment::OutputManagers>;
-#endif
-}
-
-#endif
diff --git a/paludis/environments/paludis/output_managers/Makefile.am b/paludis/environments/paludis/output_managers/Makefile.am
deleted file mode 100644
index fa920bd..0000000
--- a/paludis/environments/paludis/output_managers/Makefile.am
+++ /dev/null
@@ -1,35 +0,0 @@
-SUBDIRS = .
-CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda *.loT *.epicfail .keep
-BUILT_SOURCES =
-MAINTAINERCLEANFILES = Makefile.in
-AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
-DEFS= \
- -DSYSCONFDIR=\"$(sysconfdir)\" \
- -DLIBEXECDIR=\"$(libexecdir)\" \
- -DDATADIR=\"$(datadir)\" \
- -DLIBDIR=\"$(libdir)\"
-
-AUTOMAKE_OPTIONS = parallel-tests
-
-shareenvpaludisdir = $(datarootdir)/paludis/environments/paludis/output_managers
-
-dist_shareenvpaludis_DATA = \
- logged.conf \
- quiet.conf \
- standard.conf \
- standard_on_failure.conf \
- keep_messages.part.conf \
- keep_stdout_as_messages.part.conf \
- logged_only.part.conf \
- show_messages.part.conf
-
-logdir = @HACKED_LOG_DIR@
-
-log_DATA = .keep
-
-.keep :
- touch $@
-
-built-sources : $(BUILT_SOURCES)
- for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
-
diff --git a/paludis/environments/paludis/output_managers/keep_messages.part.conf b/paludis/environments/paludis/output_managers/keep_messages.part.conf
deleted file mode 100644
index 5cc0f7b..0000000
--- a/paludis/environments/paludis/output_managers/keep_messages.part.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-# Keep message logs, ignore stdout / stderr. Not directly usable.
-
-handler = messages_to_stdout
-child = keep_stdout_as_messages.part
-format_debug =
-format_info = --- %{message}
-format_warn = *** %{message}
-format_error = !!! %{message}
-format_log = +++ %{message}
-
diff --git a/paludis/environments/paludis/output_managers/keep_stdout_as_messages.part.conf b/paludis/environments/paludis/output_managers/keep_stdout_as_messages.part.conf
deleted file mode 100644
index 112293f..0000000
--- a/paludis/environments/paludis/output_managers/keep_stdout_as_messages.part.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-# Keep message logs. For use by keep_messages.part; do not use directly.
-
-handler = file
-stdout = ${root}/var/log/paludis/%{time}-%{action}-%{full_name}.messages
-stderr = ${stdout}
-keep_on_success = true
-keep_on_empty = false
-summary_output_manager = standard
-summary_output_stdout_message = Messages log: ${stdout}
-
diff --git a/paludis/environments/paludis/output_managers/logged.conf b/paludis/environments/paludis/output_managers/logged.conf
deleted file mode 100644
index 1e40328..0000000
--- a/paludis/environments/paludis/output_managers/logged.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-# Output to stdout / stderr, keep logs of messages and keep output logs on
-# failure.
-
-handler = tee
-children = standard logged_only.part keep_messages.part
-
diff --git a/paludis/environments/paludis/output_managers/logged_only.part.conf b/paludis/environments/paludis/output_managers/logged_only.part.conf
deleted file mode 100644
index 8b0d2b6..0000000
--- a/paludis/environments/paludis/output_managers/logged_only.part.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-# Keep logs of output only, and discard on success. Used by logged and quiet;
-# not directly usable.
-#
-handler = file
-stdout = ${root}/var/log/paludis/%{time}-%{action}-%{full_name}.out
-stderr = ${stdout}
-keep_on_success = false
-keep_on_empty = true
-summary_output_manager = standard
-summary_output_stdout_message = Output log: ${stdout}
-
diff --git a/paludis/environments/paludis/output_managers/quiet.conf b/paludis/environments/paludis/output_managers/quiet.conf
deleted file mode 100644
index 980db29..0000000
--- a/paludis/environments/paludis/output_managers/quiet.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-# Messages only to stdout / stderr, keep logs of messages and keep output logs
-# on failure.
-
-handler = tee
-children = logged_only.part show_messages.part keep_messages.part
-
diff --git a/paludis/environments/paludis/output_managers/show_messages.part.conf b/paludis/environments/paludis/output_managers/show_messages.part.conf
deleted file mode 100644
index 39cfa2c..0000000
--- a/paludis/environments/paludis/output_managers/show_messages.part.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-# Show messages only. Not usable on its own.
-
-handler = messages_to_stdout
-child = standard
-
diff --git a/paludis/environments/paludis/output_managers/standard.conf b/paludis/environments/paludis/output_managers/standard.conf
deleted file mode 100644
index 7b910c7..0000000
--- a/paludis/environments/paludis/output_managers/standard.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-# This output manager sends stdout output to stdout and stderr output to
-# stderr. There is no special handling for messages.
-
-handler = standard
diff --git a/paludis/environments/paludis/output_managers/standard_on_failure.conf b/paludis/environments/paludis/output_managers/standard_on_failure.conf
deleted file mode 100644
index f6dd6e0..0000000
--- a/paludis/environments/paludis/output_managers/standard_on_failure.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-# This handler saves up output (in memory, so don't use it for big processes)
-# and displays it to standard only if an error occurs.
-
-handler = forward_on_failure
-child = standard
-
diff --git a/paludis/environments/paludis/paludis_config.cc b/paludis/environments/paludis/paludis_config.cc
index c325dee..26cf381 100644
--- a/paludis/environments/paludis/paludis_config.cc
+++ b/paludis/environments/paludis/paludis_config.cc
@@ -25,7 +25,6 @@
#include <paludis/environments/paludis/licenses_conf.hh>
#include <paludis/environments/paludis/package_mask_conf.hh>
#include <paludis/environments/paludis/output_conf.hh>
-#include <paludis/environments/paludis/output_managers.hh>
#include <paludis/environments/paludis/world.hh>
#include <paludis/environments/paludis/extra_distribution_data.hh>
@@ -183,7 +182,6 @@ namespace paludis
std::tr1::shared_ptr<PackageMaskConf> package_unmask_conf;
std::tr1::shared_ptr<MirrorsConf> mirrors_conf;
std::tr1::shared_ptr<OutputConf> output_conf;
- std::tr1::shared_ptr<OutputManagers> output_managers;
mutable std::tr1::shared_ptr<World> world;
mutable Mutex reduced_mutex;
@@ -215,7 +213,6 @@ namespace paludis
package_unmask_conf(new PackageMaskConf(e)),
mirrors_conf(new MirrorsConf(e)),
output_conf(new OutputConf(e)),
- output_managers(new OutputManagers(e)),
has_environment_conf(false),
accept_all_breaks_portage(false),
reduced_username(getenv_with_default("PALUDIS_REDUCED_USERNAME", "paludisbuild")),
@@ -706,46 +703,6 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s
throw PaludisConfigError("No output confs found");
}
- /* output managers */
- {
- std::list<FSEntry> dirs, files;
- dirs.push_back(getenv_with_default("PALUDIS_OUTPUT_MANAGERS_DIR",
- SHAREDIR "/paludis/environments/paludis/output_managers/"));
- dirs.push_back(local_config_dir / dist->output_managers_directory());
-
- for (std::list<FSEntry>::const_iterator dir(dirs.begin()), dir_end(dirs.end()) ;
- dir != dir_end ; ++dir)
- {
- if (! dir->exists())
- continue;
-
- std::remove_copy_if(DirIterator(*dir), DirIterator(), std::back_inserter(files),
- std::tr1::bind(std::logical_not<bool>(), std::tr1::bind(&is_file_with_extension, _1, ".conf", IsFileWithOptions())));
- std::remove_copy_if(DirIterator(*dir), DirIterator(), std::back_inserter(files),
- std::tr1::bind(std::logical_not<bool>(), std::tr1::bind(&is_file_with_extension, _1, ".bash", IsFileWithOptions())));
- }
-
- bool any(false);
- for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
- file != file_end ; ++file)
- {
- Context local_context("When reading output manager file '" + stringify(*file) + "':");
-
- if (! file->exists())
- continue;
-
- std::tr1::shared_ptr<Map<std::string, std::string> > predefined_variables(
- new Map<std::string, std::string>);
- predefined_variables->insert("root", _imp->root);
- predefined_variables->insert("ROOT", _imp->root);
- _imp->output_managers->add(*file, predefined_variables);
- any = true;
- }
-
- if (! any)
- throw PaludisConfigError("No output managers found");
- }
-
/* use */
{
std::list<FSEntry> files;
@@ -1033,12 +990,6 @@ PaludisConfig::package_unmask_conf() const
return _imp->package_unmask_conf;
}
-std::tr1::shared_ptr<const OutputManagers>
-PaludisConfig::output_managers() const
-{
- return _imp->output_managers;
-}
-
std::tr1::shared_ptr<const MirrorsConf>
PaludisConfig::mirrors_conf() const
{
diff --git a/paludis/environments/paludis/paludis_config.hh b/paludis/environments/paludis/paludis_config.hh
index f3b1d94..73d9322 100644
--- a/paludis/environments/paludis/paludis_config.hh
+++ b/paludis/environments/paludis/paludis_config.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2006, 2007, 2008, 2009 Ciaran McCreesh
+ * Copyright (c) 2006, 2007, 2008, 2009, 2010 Ciaran McCreesh
*
* 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
@@ -51,7 +51,6 @@ namespace paludis
struct PackageMaskConf;
struct MirrorsConf;
struct OutputConf;
- struct OutputManagers;
struct World;
/**
@@ -122,7 +121,6 @@ namespace paludis
std::tr1::shared_ptr<const MirrorsConf> mirrors_conf() const;
std::tr1::shared_ptr<const World> world() const;
std::tr1::shared_ptr<const OutputConf> output_conf() const;
- std::tr1::shared_ptr<const OutputManagers> output_managers() const;
///\}
diff --git a/paludis/environments/paludis/paludis_environment.cc b/paludis/environments/paludis/paludis_environment.cc
index 25c4fed..8dd5bab 100644
--- a/paludis/environments/paludis/paludis_environment.cc
+++ b/paludis/environments/paludis/paludis_environment.cc
@@ -25,7 +25,6 @@
#include <paludis/environments/paludis/licenses_conf.hh>
#include <paludis/environments/paludis/mirrors_conf.hh>
#include <paludis/environments/paludis/output_conf.hh>
-#include <paludis/environments/paludis/output_managers.hh>
#include <paludis/environments/paludis/world.hh>
#include <paludis/util/config_file.hh>
@@ -489,12 +488,6 @@ PaludisEnvironment::create_output_manager(const CreateOutputManagerInfo & i) con
return _imp->config->output_conf()->create_output_manager(i);
}
-const std::tr1::shared_ptr<OutputManager>
-PaludisEnvironment::create_named_output_manager(const std::string & s, const CreateOutputManagerInfo & i) const
-{
- return _imp->config->output_managers()->create_named_output_manager(s, i);
-}
-
namespace
{
std::tr1::shared_ptr<const SetSpecTree> make_world_set(const std::tr1::shared_ptr<const World> & world)
diff --git a/paludis/environments/paludis/paludis_environment.hh b/paludis/environments/paludis/paludis_environment.hh
index 605dc4c..5be0275 100644
--- a/paludis/environments/paludis/paludis_environment.hh
+++ b/paludis/environments/paludis/paludis_environment.hh
@@ -166,10 +166,6 @@ namespace paludis
virtual const std::tr1::shared_ptr<OutputManager> create_output_manager(
const CreateOutputManagerInfo &) const;
-
- const std::tr1::shared_ptr<OutputManager> create_named_output_manager(
- const std::string &,
- const CreateOutputManagerInfo &) const;
};
}
#endif
diff --git a/paludis/environments/paludis/tests_output.conf b/paludis/environments/paludis/tests_output.conf
index 8f4e280..13161cd 100644
--- a/paludis/environments/paludis/tests_output.conf
+++ b/paludis/environments/paludis/tests_output.conf
@@ -1 +1,11 @@
-type = * : standard
+# vim: set tw=80 ft=conf et sw=4 sts=4 :
+
+# When running tests, just send everything to standard output.
+
+[rule all]
+type = *
+manager = standard
+
+[manager standard]
+handler = standard
+
diff --git a/paludis/file_output_manager.cc b/paludis/file_output_manager.cc
index ff797a5..aa9eff8 100644
--- a/paludis/file_output_manager.cc
+++ b/paludis/file_output_manager.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * Copyright (c) 2009, 2010 Ciaran McCreesh
*
* 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
@@ -35,49 +35,39 @@ namespace paludis
template <>
struct Implementation<FileOutputManager>
{
- FSEntry stdout_file;
- FSEntry stderr_file;
+ FSEntry filename;
std::tr1::shared_ptr<SafeOFStream> stdout_stream;
std::tr1::shared_ptr<SafeOFStream> stderr_stream;
const bool keep_on_success, keep_on_empty;
const std::tr1::shared_ptr<OutputManager> summary_output_manager;
- const std::string summary_output_stdout_message;
- const std::string summary_output_stderr_message;
+ const std::string summary_output_message;
- bool succeeded, unlinked_stdout, unlinked_stderr;
+ bool succeeded, unlinked;
Implementation(
const FSEntry & o,
- const FSEntry & e,
const bool k,
const bool l,
const std::tr1::shared_ptr<OutputManager> & m,
- const std::string & s,
- const std::string & t
+ const std::string & s
) :
- stdout_file(o),
- stderr_file(e),
- stdout_stream(new SafeOFStream(o)),
+ filename(o),
+ stdout_stream(new SafeOFStream(filename)),
+ stderr_stream(new SafeOFStream(filename)),
keep_on_success(k),
keep_on_empty(l),
summary_output_manager(m),
- summary_output_stdout_message(s),
- summary_output_stderr_message(t),
+ summary_output_message(s),
succeeded(false),
- unlinked_stdout(false),
- unlinked_stderr(false)
+ unlinked(false)
{
- if (o == e)
- stderr_stream = stdout_stream;
- else
- stderr_stream.reset(new SafeOFStream(e));
}
};
}
-FileOutputManager::FileOutputManager(const FSEntry & o, const FSEntry & e, const bool k, const bool l,
- const std::tr1::shared_ptr<OutputManager> & m, const std::string & s, const std::string & t) :
- PrivateImplementationPattern<FileOutputManager>(new Implementation<FileOutputManager>(o, e, k, l, m, s, t))
+FileOutputManager::FileOutputManager(const FSEntry & o, const bool k, const bool l,
+ const std::tr1::shared_ptr<OutputManager> & m, const std::string & s) :
+ PrivateImplementationPattern<FileOutputManager>(new Implementation<FileOutputManager>(o, k, l, m, s))
{
}
@@ -88,39 +78,19 @@ FileOutputManager::~FileOutputManager()
*_imp->stdout_stream << std::flush;
*_imp->stderr_stream << std::flush;
- FSEntry stdout_file_now(stringify(_imp->stdout_file)), stderr_file_now(stringify(_imp->stderr_file));
- if (stdout_file_now.exists() && 0 == stdout_file_now.file_size())
+ FSEntry filename_now(stringify(_imp->filename));
+ if (filename_now.exists() && 0 == filename_now.file_size())
{
- _imp->stdout_file.unlink();
- _imp->unlinked_stdout = true;
- }
-
- if (stdout_file_now != stderr_file_now)
- {
- if (stderr_file_now.exists() && 0 == stderr_file_now.file_size())
- {
- _imp->stderr_file.unlink();
- _imp->unlinked_stderr = true;
- }
+ filename_now.unlink();
+ _imp->unlinked = true;
}
}
if (_imp->summary_output_manager)
{
- if ((! _imp->unlinked_stdout) && (! _imp->summary_output_stdout_message.empty()))
- {
- _imp->summary_output_manager->stdout_stream()
- << _imp->summary_output_stdout_message
- << std::endl;
- }
-
- if (_imp->stdout_file != _imp->stderr_file)
- {
- if ((! _imp->unlinked_stderr) && (! _imp->summary_output_stderr_message.empty()))
- _imp->summary_output_manager->stdout_stream()
- << _imp->summary_output_stderr_message
- << std::endl;
- }
+ if ((! _imp->unlinked) && (! _imp->summary_output_message.empty()))
+ _imp->summary_output_manager->message(_imp->succeeded ? mt_info : mt_error,
+ _imp->summary_output_message);
}
}
@@ -137,21 +107,29 @@ FileOutputManager::stderr_stream()
}
void
+FileOutputManager::message(const MessageType, const std::string &)
+{
+}
+
+void
FileOutputManager::succeeded()
{
_imp->succeeded = true;
if (! _imp->keep_on_success)
{
- _imp->stdout_file.unlink();
- _imp->stderr_file.unlink();
- _imp->unlinked_stdout = true;
- _imp->unlinked_stderr = true;
+ _imp->filename.unlink();
+ _imp->unlinked = true;
}
}
void
-FileOutputManager::message(const MessageType, const std::string &)
+FileOutputManager::flush()
+{
+}
+
+void
+FileOutputManager::nothing_more_to_come()
{
}
@@ -169,19 +147,15 @@ FileOutputManager::factory_create(
const OutputManagerFactory::CreateChildFunction & create_child_function,
const OutputManagerFactory::ReplaceVarsFunc & replace_vars_func)
{
- std::string stdout_s(key_func("stdout")), stderr_s(key_func("stderr")),
- keep_on_success_s(key_func("keep_on_success")), keep_on_empty_s(key_func("keep_on_empty")),
+ std::string filename_s(key_func("filename")),
+ keep_on_success_s(key_func("keep_on_success")),
+ keep_on_empty_s(key_func("keep_on_empty")),
summary_output_manager_s(key_func("summary_output_manager")),
- summary_output_stdout_message_s(key_func("summary_output_stdout_message")),
- summary_output_stderr_message_s(key_func("summary_output_stderr_message"));
-
- if (stdout_s.empty())
- throw ConfigurationError("Key 'stdout' not specified when creating a file output manager");
- stdout_s = replace_vars_func(stdout_s, make_shared_ptr(new Map<std::string, std::string>));
+ summary_output_message_s(key_func("summary_output_message"));
- if (stderr_s.empty())
- throw ConfigurationError("Key 'stderr' not specified when creating a file output manager");
- stderr_s = replace_vars_func(stderr_s, make_shared_ptr(new Map<std::string, std::string>));
+ if (filename_s.empty())
+ throw ConfigurationError("Key 'filename' not specified when creating a file output manager");
+ filename_s = replace_vars_func(filename_s, make_shared_ptr(new Map<std::string, std::string>));
if (keep_on_success_s.empty())
keep_on_success_s = "true";
@@ -193,13 +167,11 @@ FileOutputManager::factory_create(
if (! summary_output_manager_s.empty())
summary_output_manager = create_child_function(summary_output_manager_s);
- summary_output_stdout_message_s = replace_vars_func(summary_output_stdout_message_s, make_shared_ptr(new Map<std::string, std::string>));
- summary_output_stderr_message_s = replace_vars_func(summary_output_stderr_message_s, make_shared_ptr(new Map<std::string, std::string>));
+ summary_output_message_s = replace_vars_func(summary_output_message_s, make_shared_ptr(new Map<std::string, std::string>));
- return make_shared_ptr(new FileOutputManager(FSEntry(stdout_s), FSEntry(stderr_s),
+ return make_shared_ptr(new FileOutputManager(FSEntry(filename_s),
destringify<bool>(keep_on_success_s), destringify<bool>(keep_on_empty_s),
- summary_output_manager, summary_output_stdout_message_s,
- summary_output_stderr_message_s));
+ summary_output_manager, summary_output_message_s));
}
template class PrivateImplementationPattern<FileOutputManager>;
diff --git a/paludis/file_output_manager.hh b/paludis/file_output_manager.hh
index 5009abe..31e206c 100644
--- a/paludis/file_output_manager.hh
+++ b/paludis/file_output_manager.hh
@@ -36,16 +36,19 @@ namespace paludis
public OutputManager
{
public:
- FileOutputManager(const FSEntry &, const FSEntry &, const bool keep_on_success,
- const bool keep_on_empty, const std::tr1::shared_ptr<OutputManager> & summary_output_manager,
- const std::string & summary_output_stdout_message,
- const std::string & summary_output_stderr_message);
+ FileOutputManager(const FSEntry &,
+ const bool keep_on_success,
+ const bool keep_on_empty,
+ const std::tr1::shared_ptr<OutputManager> & summary_output_manager,
+ const std::string & summary_output_message);
~FileOutputManager();
virtual std::ostream & stdout_stream() PALUDIS_ATTRIBUTE((warn_unused_result));
virtual std::ostream & stderr_stream() PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void succeeded();
+ virtual void flush();
+ virtual void nothing_more_to_come();
virtual void message(const MessageType, const std::string &);
static const std::tr1::shared_ptr<const Set<std::string> > factory_managers()
diff --git a/paludis/files.m4 b/paludis/files.m4
index b9f1470..4c346e9 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -11,6 +11,7 @@ dnl on this file at present...
add(`about', `hh', `test')
add(`action', `hh', `cc', `fwd', `se')
add(`action_names', `hh', `cc', `fwd')
+add(`buffer_output_manager', `hh', `cc', `fwd')
add(`choice', `hh', `cc', `fwd')
add(`common_sets', `hh', `cc', `fwd')
add(`contents', `hh', `cc', `fwd')
@@ -37,6 +38,7 @@ add(`filter', `hh', `cc', `fwd', `test')
add(`filter_handler', `hh', `cc', `fwd')
add(`filtered_generator', `hh', `cc', `fwd', `test')
add(`find_unused_packages_task', `hh', `cc')
+add(`format_messages_output_manager', `hh', `fwd', `cc')
add(`formatter', `hh', `fwd', `cc')
add(`forward_on_failure_output_manager', `hh', `fwd', `cc')
add(`fuzzy_finder', `hh', `cc', `test')
@@ -51,7 +53,6 @@ add(`mask', `hh', `cc', `fwd', `se')
add(`match_package', `hh', `cc', `se', `fwd')
add(`merger', `hh', `cc', `fwd', `se', `test', `testscript')
add(`merger_entry_type', `hh', `cc', `se')
-add(`messages_to_stdout_output_handler', `hh', `cc', `fwd')
add(`metadata_key', `hh', `cc', `se', `fwd')
add(`metadata_key_holder', `hh', `cc', `fwd')
add(`name', `hh', `cc', `fwd', `test')
diff --git a/paludis/format_messages_output_manager-fwd.hh b/paludis/format_messages_output_manager-fwd.hh
new file mode 100644
index 0000000..e2509d7
--- /dev/null
+++ b/paludis/format_messages_output_manager-fwd.hh
@@ -0,0 +1,28 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2010 Ciaran McCreesh
+ *
+ * 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_FORMAT_MESSAGES_OUTPUT_MANAGER_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_FORMAT_MESSAGES_OUTPUT_MANAGER_FWD_HH 1
+
+namespace paludis
+{
+ struct FormatMessagesOutputManager;
+}
+
+#endif
diff --git a/paludis/format_messages_output_manager.cc b/paludis/format_messages_output_manager.cc
new file mode 100644
index 0000000..0053e0d
--- /dev/null
+++ b/paludis/format_messages_output_manager.cc
@@ -0,0 +1,192 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2010 Ciaran McCreesh
+ *
+ * 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/format_messages_output_manager.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/discard_output_stream.hh>
+#include <paludis/util/set.hh>
+#include <paludis/util/map.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/destringify.hh>
+#include <paludis/util/stringify.hh>
+
+using namespace paludis;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<FormatMessagesOutputManager>
+ {
+ DiscardOutputStream stream;
+ const std::tr1::shared_ptr<OutputManager> child;
+ const std::string format_debug;
+ const std::string format_info;
+ const std::string format_warn;
+ const std::string format_error;
+ const std::string format_log;
+
+ const FormatMessagesOutputManagerFormatFunction format_func;
+
+ Implementation(
+ const std::tr1::shared_ptr<OutputManager> & c,
+ const std::string & d,
+ const std::string & i,
+ const std::string & w,
+ const std::string & e,
+ const std::string & l,
+ const FormatMessagesOutputManagerFormatFunction & f
+ ) :
+ child(c),
+ format_debug(d),
+ format_info(i),
+ format_warn(w),
+ format_error(e),
+ format_log(l),
+ format_func(f)
+ {
+ }
+ };
+}
+
+FormatMessagesOutputManager::FormatMessagesOutputManager(
+ const std::tr1::shared_ptr<OutputManager> & child,
+ const std::string & format_debug,
+ const std::string & format_info,
+ const std::string & format_warn,
+ const std::string & format_error,
+ const std::string & format_log,
+ const FormatMessagesOutputManagerFormatFunction & f) :
+ PrivateImplementationPattern<FormatMessagesOutputManager>(new Implementation<FormatMessagesOutputManager>(
+ child, format_debug, format_info, format_warn, format_error, format_log, f))
+{
+}
+
+FormatMessagesOutputManager::~FormatMessagesOutputManager()
+{
+}
+
+std::ostream &
+FormatMessagesOutputManager::stdout_stream()
+{
+ return _imp->stream;
+}
+
+std::ostream &
+FormatMessagesOutputManager::stderr_stream()
+{
+ return _imp->stream;
+}
+
+void
+FormatMessagesOutputManager::message(const MessageType t, const std::string & s)
+{
+ std::string f;
+ switch (t)
+ {
+ case mt_info:
+ f = _imp->format_info;
+ break;
+ case mt_debug:
+ f = _imp->format_debug;
+ break;
+ case mt_warn:
+ f = _imp->format_warn;
+ break;
+ case mt_error:
+ f = _imp->format_error;
+ break;
+ case mt_log:
+ f = _imp->format_log;
+ break;
+
+ default:
+ break;
+ }
+
+ if (f.empty())
+ return;
+
+ f = _imp->format_func(f, s);
+ _imp->child->stdout_stream() << f << std::flush;
+}
+
+void
+FormatMessagesOutputManager::succeeded()
+{
+ _imp->child->succeeded();
+}
+
+void
+FormatMessagesOutputManager::flush()
+{
+ _imp->child->flush();
+}
+
+void
+FormatMessagesOutputManager::nothing_more_to_come()
+{
+ _imp->child->nothing_more_to_come();
+}
+
+const std::tr1::shared_ptr<const Set<std::string> >
+FormatMessagesOutputManager::factory_managers()
+{
+ std::tr1::shared_ptr<Set<std::string> > result(new Set<std::string>);
+ result->insert("format_messages");
+ return result;
+}
+
+namespace
+{
+ std::string format_message(
+ const OutputManagerFactory::ReplaceVarsFunc r,
+ const std::string & f,
+ const std::string & s)
+ {
+ std::tr1::shared_ptr<Map<std::string, std::string> > m(new Map<std::string, std::string>);
+ m->insert("message", s);
+ return r(f, m);
+ }
+}
+
+const std::tr1::shared_ptr<OutputManager>
+FormatMessagesOutputManager::factory_create(
+ const OutputManagerFactory::KeyFunction & key_func,
+ const OutputManagerFactory::CreateChildFunction & create_child_function,
+ const OutputManagerFactory::ReplaceVarsFunc & replace_vars_func)
+{
+ std::string child_s(key_func("child")),
+ format_debug_s(key_func("format_debug")),
+ format_info_s(key_func("format_info")),
+ format_warn_s(key_func("format_warn")),
+ format_error_s(key_func("format_error")),
+ format_log_s(key_func("format_log"));
+
+ std::tr1::shared_ptr<OutputManager> child(create_child_function(child_s));
+
+ FormatMessagesOutputManagerFormatFunction format_func(std::tr1::bind(
+ &format_message, replace_vars_func, std::tr1::placeholders::_1, std::tr1::placeholders::_2));
+
+ return make_shared_ptr(new FormatMessagesOutputManager(
+ child, format_debug_s, format_info_s, format_warn_s, format_error_s, format_log_s, format_func));
+}
+
+template class PrivateImplementationPattern<FormatMessagesOutputManager>;
+
diff --git a/paludis/format_messages_output_manager.hh b/paludis/format_messages_output_manager.hh
new file mode 100644
index 0000000..6aafba8
--- /dev/null
+++ b/paludis/format_messages_output_manager.hh
@@ -0,0 +1,76 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2010 Ciaran McCreesh
+ *
+ * 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_FORMAT_MESSAGES_OUTPUT_MANAGER_HH
+#define PALUDIS_GUARD_PALUDIS_FORMAT_MESSAGES_OUTPUT_MANAGER_HH 1
+
+#include <paludis/format_messages_output_manager-fwd.hh>
+#include <paludis/output_manager.hh>
+#include <paludis/output_manager_factory.hh>
+#include <paludis/util/set-fwd.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <tr1/memory>
+#include <tr1/functional>
+
+namespace paludis
+{
+ typedef std::tr1::function<std::string (
+ const std::string &,
+ const std::string &)> FormatMessagesOutputManagerFormatFunction;
+
+ class PALUDIS_VISIBLE FormatMessagesOutputManager :
+ private PrivateImplementationPattern<FormatMessagesOutputManager>,
+ public OutputManager
+ {
+ public:
+ FormatMessagesOutputManager(
+ const std::tr1::shared_ptr<OutputManager> & child,
+ const std::string & format_debug,
+ const std::string & format_info,
+ const std::string & format_warn,
+ const std::string & format_error,
+ const std::string & format_log,
+ const FormatMessagesOutputManagerFormatFunction &);
+
+ ~FormatMessagesOutputManager();
+
+ virtual std::ostream & stdout_stream() PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual std::ostream & stderr_stream() PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ virtual void succeeded();
+ virtual void flush();
+ virtual void nothing_more_to_come();
+ virtual void message(const MessageType, const std::string &);
+
+ static const std::tr1::shared_ptr<const Set<std::string> > factory_managers()
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ static const std::tr1::shared_ptr<OutputManager> factory_create(
+ const OutputManagerFactory::KeyFunction &,
+ const OutputManagerFactory::CreateChildFunction &,
+ const OutputManagerFactory::ReplaceVarsFunc &)
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class PrivateImplementationPattern<FormatMessagesOutputManager>;
+#endif
+}
+
+#endif
diff --git a/paludis/forward_on_failure_output_manager.cc b/paludis/forward_on_failure_output_manager.cc
index 2113544..fe16c76 100644
--- a/paludis/forward_on_failure_output_manager.cc
+++ b/paludis/forward_on_failure_output_manager.cc
@@ -90,6 +90,16 @@ ForwardOnFailureOutputManager::message(const MessageType, const std::string &)
{
}
+void
+ForwardOnFailureOutputManager::flush()
+{
+}
+
+void
+ForwardOnFailureOutputManager::nothing_more_to_come()
+{
+}
+
const std::tr1::shared_ptr<const Set<std::string> >
ForwardOnFailureOutputManager::factory_managers()
{
diff --git a/paludis/forward_on_failure_output_manager.hh b/paludis/forward_on_failure_output_manager.hh
index a5e0611..1ac69b2 100644
--- a/paludis/forward_on_failure_output_manager.hh
+++ b/paludis/forward_on_failure_output_manager.hh
@@ -42,7 +42,9 @@ namespace paludis
virtual std::ostream & stderr_stream() PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void succeeded();
+ virtual void flush();
virtual void message(const MessageType, const std::string &);
+ virtual void nothing_more_to_come();
static const std::tr1::shared_ptr<const Set<std::string> > factory_managers()
PALUDIS_ATTRIBUTE((warn_unused_result));
diff --git a/paludis/messages_to_stdout_output_handler.cc b/paludis/messages_to_stdout_output_handler.cc
deleted file mode 100644
index 0492fe4..0000000
--- a/paludis/messages_to_stdout_output_handler.cc
+++ /dev/null
@@ -1,171 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2009 Ciaran McCreesh
- *
- * 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
- * Public License version 2, as published by the Free Software Foundation.
- *
- * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <paludis/messages_to_stdout_output_handler.hh>
-#include <paludis/util/private_implementation_pattern-impl.hh>
-#include <paludis/util/discard_output_stream.hh>
-#include <paludis/util/sequence-impl.hh>
-#include <paludis/util/set.hh>
-#include <paludis/util/wrapped_forward_iterator.hh>
-#include <paludis/util/make_shared_ptr.hh>
-#include <paludis/util/exception.hh>
-#include <paludis/util/map.hh>
-#include <paludis/util/stringify.hh>
-
-using namespace paludis;
-
-namespace paludis
-{
- template <>
- struct Implementation<MessagesToStdoutOutputManager>
- {
- DiscardOutputStream output_stream;
- const std::tr1::shared_ptr<OutputManager> child;
- const OutputManagerFactory::ReplaceVarsFunc replace_vars_func;
- const std::string f_debug;
- const std::string f_info;
- const std::string f_warn;
- const std::string f_error;
- const std::string f_log;
-
- Implementation(
- const std::tr1::shared_ptr<OutputManager> & c,
- const OutputManagerFactory::ReplaceVarsFunc & r,
- const std::string & f_d,
- const std::string & f_i,
- const std::string & f_w,
- const std::string & f_e,
- const std::string & f_l) :
- child(c),
- replace_vars_func(r),
- f_debug(f_d),
- f_info(f_i),
- f_warn(f_w),
- f_error(f_e),
- f_log(f_l)
- {
- }
- };
-}
-
-MessagesToStdoutOutputManager::MessagesToStdoutOutputManager(
- const std::tr1::shared_ptr<OutputManager> & s,
- const OutputManagerFactory::ReplaceVarsFunc & replace_vars_func,
- const std::string & f_debug,
- const std::string & f_info,
- const std::string & f_warn,
- const std::string & f_error,
- const std::string & f_log) :
- PrivateImplementationPattern<MessagesToStdoutOutputManager>(new Implementation<MessagesToStdoutOutputManager>(s, replace_vars_func,
- f_debug, f_info, f_warn, f_error, f_log))
-{
-}
-
-MessagesToStdoutOutputManager::~MessagesToStdoutOutputManager()
-{
-}
-
-std::ostream &
-MessagesToStdoutOutputManager::stdout_stream()
-{
- return _imp->output_stream;
-}
-
-std::ostream &
-MessagesToStdoutOutputManager::stderr_stream()
-{
- return _imp->output_stream;
-}
-
-void
-MessagesToStdoutOutputManager::succeeded()
-{
- _imp->child->succeeded();
-}
-
-void
-MessagesToStdoutOutputManager::message(const MessageType t, const std::string & s)
-{
- std::string msg;
- std::tr1::shared_ptr<Map<std::string, std::string> > x(new Map<std::string, std::string>);
- x->insert("message", s);
-
- do
- {
- switch (t)
- {
- case mt_debug:
- msg = _imp->replace_vars_func(_imp->f_debug, x);
- continue;
-
- case mt_info:
- msg = _imp->replace_vars_func(_imp->f_info, x);
- continue;
-
- case mt_warn:
- msg = _imp->replace_vars_func(_imp->f_warn, x);
- continue;
-
- case mt_error:
- msg = _imp->replace_vars_func(_imp->f_error, x);
- continue;
-
- case mt_log:
- msg = _imp->replace_vars_func(_imp->f_log, x);
- continue;
-
- case last_mt:
- break;
- }
-
- throw InternalError(PALUDIS_HERE, "bad MessageType");
- }
- while (false);
-
- if (! msg.empty())
- _imp->child->stdout_stream() << msg << std::endl;
-}
-
-const std::tr1::shared_ptr<const Set<std::string> >
-MessagesToStdoutOutputManager::factory_managers()
-{
- std::tr1::shared_ptr<Set<std::string> > result(new Set<std::string>);
- result->insert("messages_to_stdout");
- return result;
-}
-
-const std::tr1::shared_ptr<OutputManager>
-MessagesToStdoutOutputManager::factory_create(
- const OutputManagerFactory::KeyFunction & key_func,
- const OutputManagerFactory::CreateChildFunction & create_child,
- const OutputManagerFactory::ReplaceVarsFunc & replace_vars_func)
-{
- std::string child(key_func("child"));
- if (child.empty())
- throw ConfigurationError("No child specified for MessagesToStdoutOutputManager");
-
- std::string f_d(key_func("format_debug")), f_i(key_func("format_info")), f_w(key_func("format_warn")),
- f_e(key_func("format_error")), f_l(key_func("format_log"));
-
- return make_shared_ptr(new MessagesToStdoutOutputManager(create_child(child), replace_vars_func,
- f_d, f_i, f_w, f_e, f_l));
-}
-
-template class PrivateImplementationPattern<MessagesToStdoutOutputManager>;
-
diff --git a/paludis/output_manager.hh b/paludis/output_manager.hh
index 8c0dfa9..1edee95 100644
--- a/paludis/output_manager.hh
+++ b/paludis/output_manager.hh
@@ -46,6 +46,15 @@ namespace paludis
virtual void message(const MessageType, const std::string &) = 0;
/**
+ * Clients may call this method every few seconds when running
+ * multiple processes.
+ *
+ * This is used to display ongoing buffered messages without mixing
+ * output from multiple processes.
+ */
+ virtual void flush() = 0;
+
+ /**
* Called if an action succeeds. This can be used to, for example,
* unlink the files behind a to-disk logged output manager.
*
@@ -60,6 +69,18 @@ namespace paludis
* carries out the action in question.
*/
virtual void succeeded() = 0;
+
+ /**
+ * May be called to indicate that no further output or messages
+ * will occur, allowing for files to be closed off etc.
+ *
+ * Summary messages are shown when the output manager is
+ * destructed, not when this method is called.
+ *
+ * If this method and succeeded are both to be called, succeeded
+ * must be called first.
+ */
+ virtual void nothing_more_to_come() = 0;
};
}
diff --git a/paludis/output_manager_factory.cc b/paludis/output_manager_factory.cc
index 0013e1e..c262ac2 100644
--- a/paludis/output_manager_factory.cc
+++ b/paludis/output_manager_factory.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * Copyright (c) 2009, 2010 Ciaran McCreesh
*
* 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
@@ -34,9 +34,9 @@
#include <tr1/unordered_map>
#include <list>
+#include <paludis/buffer_output_manager.hh>
#include <paludis/file_output_manager.hh>
-#include <paludis/forward_on_failure_output_manager.hh>
-#include <paludis/messages_to_stdout_output_handler.hh>
+#include <paludis/format_messages_output_manager.hh>
#include <paludis/standard_output_manager.hh>
#include <paludis/tee_output_manager.hh>
@@ -67,7 +67,7 @@ namespace
Keys::const_iterator i(keys.find(key));
if (i == keys.end())
throw ConfigurationError("Format '" + key + "' not supported when creating an output manager (known formats are { "
- + join(first_iterator(keys.begin()), first_iterator(keys.end()), ", ") + "})");
+ + join(first_iterator(keys.begin()), first_iterator(keys.end()), ", ") + " })");
return i->second;
}
@@ -93,9 +93,9 @@ OutputManagerFactory::OutputManagerFactory() :
PrivateImplementationPattern<OutputManagerFactory>(new Implementation<OutputManagerFactory>)
{
/* we might want to make this plugin loadable at some point */
+ add_manager(BufferOutputManager::factory_managers(), BufferOutputManager::factory_create);
add_manager(FileOutputManager::factory_managers(), FileOutputManager::factory_create);
- add_manager(ForwardOnFailureOutputManager::factory_managers(), ForwardOnFailureOutputManager::factory_create);
- add_manager(MessagesToStdoutOutputManager::factory_managers(), MessagesToStdoutOutputManager::factory_create);
+ add_manager(FormatMessagesOutputManager::factory_managers(), FormatMessagesOutputManager::factory_create);
add_manager(StandardOutputManager::factory_managers(), StandardOutputManager::factory_create);
add_manager(TeeOutputManager::factory_managers(), TeeOutputManager::factory_create);
}
diff --git a/paludis/standard_output_manager.cc b/paludis/standard_output_manager.cc
index 881ffdd..ef4fd24 100644
--- a/paludis/standard_output_manager.cc
+++ b/paludis/standard_output_manager.cc
@@ -50,6 +50,16 @@ StandardOutputManager::succeeded()
}
void
+StandardOutputManager::flush()
+{
+}
+
+void
+StandardOutputManager::nothing_more_to_come()
+{
+}
+
+void
StandardOutputManager::message(const MessageType, const std::string &)
{
}
diff --git a/paludis/standard_output_manager.hh b/paludis/standard_output_manager.hh
index 5d2cf46..f70cb77 100644
--- a/paludis/standard_output_manager.hh
+++ b/paludis/standard_output_manager.hh
@@ -40,7 +40,9 @@ namespace paludis
virtual std::ostream & stderr_stream() PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void succeeded();
+ virtual void flush();
virtual void message(const MessageType, const std::string &);
+ virtual void nothing_more_to_come();
static const std::tr1::shared_ptr<const Set<std::string> > factory_managers()
PALUDIS_ATTRIBUTE((warn_unused_result));
diff --git a/paludis/tee_output_manager.cc b/paludis/tee_output_manager.cc
index 167c11c..3021900 100644
--- a/paludis/tee_output_manager.cc
+++ b/paludis/tee_output_manager.cc
@@ -35,22 +35,27 @@ namespace paludis
struct Implementation<TeeOutputManager>
{
const std::tr1::shared_ptr<const Sequence<std::tr1::shared_ptr<OutputManager> > > streams;
+ const std::tr1::shared_ptr<const Sequence<std::tr1::shared_ptr<OutputManager> > > messages_streams;
+
TeeOutputStream stdout_stream;
TeeOutputStream stderr_stream;
Implementation(
- const std::tr1::shared_ptr<const Sequence<std::tr1::shared_ptr<OutputManager> > > & s) :
- streams(s)
+ const std::tr1::shared_ptr<const Sequence<std::tr1::shared_ptr<OutputManager> > > & s,
+ const std::tr1::shared_ptr<const Sequence<std::tr1::shared_ptr<OutputManager> > > & ss) :
+ streams(s),
+ messages_streams(ss)
{
}
};
}
TeeOutputManager::TeeOutputManager(
- const std::tr1::shared_ptr<const OutputManagerSequence> & s) :
- PrivateImplementationPattern<TeeOutputManager>(new Implementation<TeeOutputManager>(s))
+ const std::tr1::shared_ptr<const OutputManagerSequence> & s,
+ const std::tr1::shared_ptr<const OutputManagerSequence> & ss) :
+ PrivateImplementationPattern<TeeOutputManager>(new Implementation<TeeOutputManager>(s, ss))
{
- for (OutputManagerSequence::ConstIterator i(s->begin()), i_end(s->end()) ;
+ for (OutputManagerSequence::ConstIterator i(_imp->streams->begin()), i_end(_imp->streams->end()) ;
i != i_end ; ++i)
{
_imp->stdout_stream.add_stream(&(*i)->stdout_stream());
@@ -75,19 +80,47 @@ TeeOutputManager::stderr_stream()
}
void
+TeeOutputManager::message(const MessageType t, const std::string & m)
+{
+ for (OutputManagerSequence::ConstIterator i(_imp->messages_streams->begin()), i_end(_imp->messages_streams->end()) ;
+ i != i_end ; ++i)
+ (*i)->message(t, m);
+}
+
+void
TeeOutputManager::succeeded()
{
for (OutputManagerSequence::ConstIterator i(_imp->streams->begin()), i_end(_imp->streams->end()) ;
i != i_end ; ++i)
(*i)->succeeded();
+
+ for (OutputManagerSequence::ConstIterator i(_imp->messages_streams->begin()), i_end(_imp->messages_streams->end()) ;
+ i != i_end ; ++i)
+ (*i)->succeeded();
}
void
-TeeOutputManager::message(const MessageType t, const std::string & s)
+TeeOutputManager::flush()
{
for (OutputManagerSequence::ConstIterator i(_imp->streams->begin()), i_end(_imp->streams->end()) ;
i != i_end ; ++i)
- (*i)->message(t, s);
+ (*i)->flush();
+
+ for (OutputManagerSequence::ConstIterator i(_imp->messages_streams->begin()), i_end(_imp->messages_streams->end()) ;
+ i != i_end ; ++i)
+ (*i)->flush();
+}
+
+void
+TeeOutputManager::nothing_more_to_come()
+{
+ for (OutputManagerSequence::ConstIterator i(_imp->streams->begin()), i_end(_imp->streams->end()) ;
+ i != i_end ; ++i)
+ (*i)->nothing_more_to_come();
+
+ for (OutputManagerSequence::ConstIterator i(_imp->messages_streams->begin()), i_end(_imp->messages_streams->end()) ;
+ i != i_end ; ++i)
+ (*i)->nothing_more_to_come();
}
const std::tr1::shared_ptr<const Set<std::string> >
@@ -105,17 +138,25 @@ TeeOutputManager::factory_create(
const OutputManagerFactory::ReplaceVarsFunc &)
{
std::tr1::shared_ptr<OutputManagerSequence> children(new OutputManagerSequence);
+ std::tr1::shared_ptr<OutputManagerSequence> messages_children(new OutputManagerSequence);
std::vector<std::string> children_keys;
tokenise_whitespace(key_func("children"), std::back_inserter(children_keys));
if (children_keys.empty())
throw ConfigurationError("No children specified for TeeOutputManager");
+ std::vector<std::string> messages_children_keys;
+ tokenise_whitespace(key_func("messages_children"), std::back_inserter(messages_children_keys));
+
for (std::vector<std::string>::const_iterator c(children_keys.begin()), c_end(children_keys.end()) ;
c != c_end ; ++c)
children->push_back(create_child(*c));
- return make_shared_ptr(new TeeOutputManager(children));
+ for (std::vector<std::string>::const_iterator c(messages_children_keys.begin()), c_end(messages_children_keys.end()) ;
+ c != c_end ; ++c)
+ messages_children->push_back(create_child(*c));
+
+ return make_shared_ptr(new TeeOutputManager(children, messages_children));
}
template class PrivateImplementationPattern<TeeOutputManager>;
diff --git a/paludis/tee_output_manager.hh b/paludis/tee_output_manager.hh
index 2a47bfb..7bc59f1 100644
--- a/paludis/tee_output_manager.hh
+++ b/paludis/tee_output_manager.hh
@@ -36,13 +36,17 @@ namespace paludis
public OutputManager
{
public:
- TeeOutputManager(const std::tr1::shared_ptr<const OutputManagerSequence> &);
+ TeeOutputManager(
+ const std::tr1::shared_ptr<const OutputManagerSequence> &,
+ const std::tr1::shared_ptr<const OutputManagerSequence> &);
~TeeOutputManager();
virtual std::ostream & stdout_stream() PALUDIS_ATTRIBUTE((warn_unused_result));
virtual std::ostream & stderr_stream() PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void succeeded();
+ virtual void flush();
+ virtual void nothing_more_to_come();
virtual void message(const MessageType, const std::string &);
static const std::tr1::shared_ptr<const Set<std::string> > factory_managers()
diff --git a/paludis/util/executor.cc b/paludis/util/executor.cc
index 90fec4e..7803673 100644
--- a/paludis/util/executor.cc
+++ b/paludis/util/executor.cc
@@ -106,7 +106,7 @@ Executor::add(const std::tr1::shared_ptr<Executive> & x)
void
Executor::execute()
{
- typedef std::map<std::string, std::tr1::shared_ptr<Thread> > Running;
+ typedef std::map<std::string, std::pair<std::tr1::shared_ptr<Thread>, std::tr1::shared_ptr<Executive> > > Running;
Running running;
Lock lock(_imp->mutex);
@@ -125,8 +125,8 @@ Executor::execute()
++_imp->active;
--_imp->pending;
q->second->pre_execute_exclusive();
- running.insert(std::make_pair(q->first, make_shared_ptr(new Thread(
- std::tr1::bind(&Executor::_one, this, q->second)))));
+ running.insert(std::make_pair(q->first, std::make_pair(make_shared_ptr(new Thread(
+ std::tr1::bind(&Executor::_one, this, q->second))), q->second)));
_imp->queues.erase(q++);
any = true;
}
@@ -134,7 +134,11 @@ Executor::execute()
if ((! any) && running.empty())
break;
- _imp->condition.wait(_imp->mutex);
+ _imp->condition.timed_wait(_imp->mutex, 1);
+
+ for (Running::iterator r(running.begin()), r_end(running.end()) ;
+ r != r_end ; ++r)
+ r->second.second->flush_threaded();
for (ReadyForPost::iterator p(_imp->ready_for_post.begin()), p_end(_imp->ready_for_post.end()) ;
p != p_end ; ++p)
diff --git a/paludis/util/executor.hh b/paludis/util/executor.hh
index e468de2..7c82d12 100644
--- a/paludis/util/executor.hh
+++ b/paludis/util/executor.hh
@@ -38,6 +38,7 @@ namespace paludis
virtual void pre_execute_exclusive() = 0;
virtual void execute_threaded() = 0;
+ virtual void flush_threaded() = 0;
virtual void post_execute_exclusive() = 0;
};
diff --git a/src/clients/cave/cmd_sync.cc b/src/clients/cave/cmd_sync.cc
index 6f0c55d..52d4a1a 100644
--- a/src/clients/cave/cmd_sync.cc
+++ b/src/clients/cave/cmd_sync.cc
@@ -31,6 +31,7 @@
#include <paludis/util/thread.hh>
#include <paludis/util/return_literal_function.hh>
#include <paludis/util/executor.hh>
+#include <paludis/util/timestamp.hh>
#include <paludis/output_manager.hh>
#include <paludis/repository.hh>
#include <paludis/environment.hh>
@@ -99,6 +100,8 @@ namespace
const Executor * const executor;
const RepositoryName name;
+ Timestamp last_flushed;
+
std::tr1::shared_ptr<OutputManager> output_manager;
SyncExecutive(
@@ -112,7 +115,8 @@ namespace
env(e),
cmdline(c),
executor(x),
- name(n)
+ name(n),
+ last_flushed(0, 0)
{
}
@@ -201,15 +205,34 @@ namespace
}
}
- virtual void post_execute_exclusive()
+ void display_active()
{
- if (abort)
+ if (output_manager)
+ {
+ cout << format_general_spad(f::sync_repo_active(), stringify(name), executor->pending(),
+ executor->active(), executor->done());
+ output_manager->flush();
+ }
+ }
+
+ virtual void flush_threaded()
+ {
+ Timestamp now(Timestamp::now());
+ if (last_flushed.seconds() + 5 < now.seconds())
return;
+ last_flushed = now;
+
+ display_active();
+ }
+ virtual void post_execute_exclusive()
+ {
try
{
if (! abort)
{
+ display_active();
+
if (0 != env->perform_hook(Hook(success ? "sync_post" : "sync_fail")
("TARGET", stringify(name))
("NUMBER_DONE", stringify(executor->done()))
@@ -276,7 +299,7 @@ namespace
{
retcode |= 1;
cout << format_general_kv(f::sync_message_failure(), stringify((*x)->name), "failed");
- cout << format_general_kv(f::sync_message_failure_message(), "error", (*x)->error);
+ cout << format_general_s(f::sync_message_failure_message(), (*x)->error);
}
else
{
diff --git a/src/clients/cave/formats.cc b/src/clients/cave/formats.cc
index 1420667..351154c 100644
--- a/src/clients/cave/formats.cc
+++ b/src/clients/cave/formats.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2008, 2009 Ciaran McCreesh
+ * Copyright (c) 2008, 2009, 2010 Ciaran McCreesh
*
* 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
@@ -481,7 +481,7 @@ paludis::cave::f::sync_message_failure()
const std::string
paludis::cave::f::sync_message_failure_message()
{
- return " %k:%{column 30}%v\\n";
+ return " %s\\n";
}
const std::string