aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Piotr Jaroszyński <peper@gentoo.org> 2007-05-14 00:11:34 +0000
committerAvatar Piotr Jaroszyński <peper@gentoo.org> 2007-05-14 00:11:34 +0000
commitfae6a418974cbdf6462aaee9807671f6214d7c67 (patch)
tree2940839105d174d23a331ef18d6f3178e712f88c
parenta28fdd4abd25cfed3fc3184ef670a1be7cbfa2c5 (diff)
downloadpaludis-fae6a418974cbdf6462aaee9807671f6214d7c67.tar.gz
paludis-fae6a418974cbdf6462aaee9807671f6214d7c67.tar.xz
Now we can grab output of Hooks.
-rw-r--r--paludis/environment.hh6
-rw-r--r--paludis/environment_implementation.cc4
-rw-r--r--paludis/environment_implementation.hh2
-rw-r--r--paludis/environments/adapted/adapted_environment.cc2
-rw-r--r--paludis/environments/adapted/adapted_environment.hh2
-rw-r--r--paludis/environments/paludis/paludis_environment.cc2
-rw-r--r--paludis/environments/paludis/paludis_environment.hh2
-rw-r--r--paludis/environments/portage/portage_environment.cc2
-rw-r--r--paludis/environments/portage/portage_environment.hh2
-rw-r--r--paludis/files.m42
-rw-r--r--paludis/hook.cc57
-rw-r--r--paludis/hook.hh31
-rw-r--r--paludis/hook.se18
-rw-r--r--paludis/hook.sr22
-rw-r--r--paludis/hooker.cc136
-rw-r--r--paludis/hooker.hh5
-rw-r--r--paludis/hooker_TEST.cc106
-rwxr-xr-xpaludis/hooker_TEST_setup.sh101
-rw-r--r--paludis/merger/merger.cc48
-rw-r--r--paludis/merger/unmerger.cc16
-rw-r--r--paludis/repositories/gentoo/portage_repository.cc4
-rw-r--r--paludis/repositories/gentoo/portage_repository.hh2
-rw-r--r--paludis/repositories/gentoo/vdb_repository.cc4
-rw-r--r--paludis/repositories/gentoo/vdb_repository.hh2
-rw-r--r--paludis/repositories/gentoo/vdb_unmerger.cc4
-rw-r--r--paludis/repositories/virtuals/installed_virtuals_repository.cc4
-rw-r--r--paludis/repositories/virtuals/installed_virtuals_repository.hh2
-rw-r--r--paludis/repository-fwd.hh1
-rw-r--r--paludis/repository.hh4
-rw-r--r--paludis/tasks/install_task.cc38
-rw-r--r--paludis/tasks/install_task.hh2
-rw-r--r--paludis/tasks/sync_task.cc10
-rw-r--r--paludis/tasks/uninstall_task.cc10
-rw-r--r--src/clients/paludis/install.cc2
34 files changed, 532 insertions, 123 deletions
diff --git a/paludis/environment.hh b/paludis/environment.hh
index 36ea97c..ebddb34 100644
--- a/paludis/environment.hh
+++ b/paludis/environment.hh
@@ -26,6 +26,7 @@
#include <paludis/util/fs_entry.hh>
#include <paludis/mask_reasons.hh>
#include <paludis/name.hh>
+#include <paludis/hook.hh>
#include <paludis/repository-fwd.hh>
/** \file
@@ -36,7 +37,6 @@
namespace paludis
{
- class Hook;
class PackageDatabase;
class PackageDatabaseEntry;
class DepSpec;
@@ -257,9 +257,9 @@ namespace paludis
///\{
/**
- * Perform a hook, return the highest exit status.
+ * Perform a hook.
*/
- virtual int perform_hook(const Hook &) const
+ virtual HookResult perform_hook(const Hook &) const
PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
///\}
diff --git a/paludis/environment_implementation.cc b/paludis/environment_implementation.cc
index cfa2cb6..d5f52cf 100644
--- a/paludis/environment_implementation.cc
+++ b/paludis/environment_implementation.cc
@@ -217,10 +217,10 @@ EnvironmentImplementation::set_names() const
return result;
}
-int
+HookResult
EnvironmentImplementation::perform_hook(const Hook &) const
{
- return 0;
+ return HookResult(0, "");
}
std::tr1::shared_ptr<const DestinationsCollection>
diff --git a/paludis/environment_implementation.hh b/paludis/environment_implementation.hh
index 8520af8..37232ed 100644
--- a/paludis/environment_implementation.hh
+++ b/paludis/environment_implementation.hh
@@ -154,7 +154,7 @@ namespace paludis
virtual std::tr1::shared_ptr<const DestinationsCollection> default_destinations() const
PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual int perform_hook(const Hook &) const
+ virtual HookResult perform_hook(const Hook &) const
PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/paludis/environments/adapted/adapted_environment.cc b/paludis/environments/adapted/adapted_environment.cc
index dba2c22..21fad70 100644
--- a/paludis/environments/adapted/adapted_environment.cc
+++ b/paludis/environments/adapted/adapted_environment.cc
@@ -204,7 +204,7 @@ AdaptedEnvironment::default_destinations() const
return _imp->env->default_destinations();
}
-int
+HookResult
AdaptedEnvironment::perform_hook(const Hook & h) const
{
return _imp->env->perform_hook(h);
diff --git a/paludis/environments/adapted/adapted_environment.hh b/paludis/environments/adapted/adapted_environment.hh
index 7cff193..0ee5dda 100644
--- a/paludis/environments/adapted/adapted_environment.hh
+++ b/paludis/environments/adapted/adapted_environment.hh
@@ -115,7 +115,7 @@ namespace paludis
virtual std::tr1::shared_ptr<const DestinationsCollection> default_destinations() const
PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual int perform_hook(const Hook &) const
+ virtual HookResult perform_hook(const Hook &) const
PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/paludis/environments/paludis/paludis_environment.cc b/paludis/environments/paludis/paludis_environment.cc
index 870c72b..62b46e1 100644
--- a/paludis/environments/paludis/paludis_environment.cc
+++ b/paludis/environments/paludis/paludis_environment.cc
@@ -266,7 +266,7 @@ PaludisEnvironment::set_paludis_command(const std::string & s)
_imp->paludis_command = s;
}
-int
+HookResult
PaludisEnvironment::perform_hook(const Hook & hook) const
{
if (! _imp->hooker)
diff --git a/paludis/environments/paludis/paludis_environment.hh b/paludis/environments/paludis/paludis_environment.hh
index 0446388..d1954c3 100644
--- a/paludis/environments/paludis/paludis_environment.hh
+++ b/paludis/environments/paludis/paludis_environment.hh
@@ -117,7 +117,7 @@ namespace paludis
virtual std::tr1::shared_ptr<const SetNameCollection> set_names() const
PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual int perform_hook(const Hook &) const
+ virtual HookResult perform_hook(const Hook &) const
PALUDIS_ATTRIBUTE((warn_unused_result));
virtual std::string paludis_command() const
diff --git a/paludis/environments/portage/portage_environment.cc b/paludis/environments/portage/portage_environment.cc
index 6597643..7c9a5e4 100644
--- a/paludis/environments/portage/portage_environment.cc
+++ b/paludis/environments/portage/portage_environment.cc
@@ -594,7 +594,7 @@ PortageEnvironment::known_use_expand_names(const UseFlagName & prefix,
return result;
}
-int
+HookResult
PortageEnvironment::perform_hook(const Hook & hook) const
{
using namespace std::tr1::placeholders;
diff --git a/paludis/environments/portage/portage_environment.hh b/paludis/environments/portage/portage_environment.hh
index c42af6c..95635b7 100644
--- a/paludis/environments/portage/portage_environment.hh
+++ b/paludis/environments/portage/portage_environment.hh
@@ -110,7 +110,7 @@ namespace paludis
virtual std::tr1::shared_ptr<const MirrorsCollection> mirrors(const std::string &) const
PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual int perform_hook(const Hook &) const
+ virtual HookResult perform_hook(const Hook &) const
PALUDIS_ATTRIBUTE((warn_unused_result));
virtual std::tr1::shared_ptr<PackageDatabase> package_database()
diff --git a/paludis/files.m4 b/paludis/files.m4
index 1e690a9..b6c25a0 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -18,7 +18,7 @@ add(`dep_tag', `hh', `cc', `sr')
add(`environment', `hh', `cc', `se')
add(`environment_implementation', `hh', `cc', `test')
add(`hashed_containers', `hhx', `cc', `test')
-add(`hook', `hh', `cc')
+add(`hook', `hh', `cc', `se', `sr')
add(`hooker', `hh', `cc', `test', `testscript')
add(`host_tuple_name', `hh', `cc', `sr', `test')
add(`mask_reasons', `hh', `cc', `se')
diff --git a/paludis/hook.cc b/paludis/hook.cc
index 86ef44f..dbfd699 100644
--- a/paludis/hook.cc
+++ b/paludis/hook.cc
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2005, 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2007 Piotr Jaroszyński <peper@gentoo.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
@@ -22,6 +23,9 @@
using namespace paludis;
+#include <paludis/hook-se.cc>
+#include <paludis/hook-sr.cc>
+
namespace paludis
{
template<>
@@ -29,22 +33,29 @@ namespace paludis
{
std::string name;
std::map<std::string, std::string> extra_env;
+ std::set<std::string> allowed_values;
- Implementation(const std::string & n, const std::map<std::string, std::string> & e) :
+ Implementation(const std::string & n, const std::map<std::string, std::string> & e,
+ const std::set<std::string> & av) :
name(n),
- extra_env(e)
+ extra_env(e),
+ allowed_values(av)
{
}
};
}
Hook::Hook(const std::string & n) :
- PrivateImplementationPattern<Hook>(new Implementation<Hook>(n, std::map<std::string, std::string>()))
+ PrivateImplementationPattern<Hook>(new Implementation<Hook>(n, std::map<std::string, std::string>(),
+ std::set<std::string>())),
+ output_dest(hod_stdout)
{
}
Hook::Hook(const Hook & h) :
- PrivateImplementationPattern<Hook>(new Implementation<Hook>(h._imp->name, h._imp->extra_env))
+ PrivateImplementationPattern<Hook>(new Implementation<Hook>(h._imp->name, h._imp->extra_env,
+ h._imp->allowed_values)),
+ output_dest(h.output_dest)
{
}
@@ -60,6 +71,24 @@ Hook::operator() (const std::string & k, const std::string & v) const
return result;
}
+Hook
+Hook::grab_output(const AllowedOutputValues & av)
+{
+ Hook result(*this);
+ result.output_dest = hod_grab;
+ result._imp->allowed_values = av.allowed_values;
+ return result;
+}
+
+bool
+Hook::validate_value(const std::string & v) const
+{
+ if (_imp->allowed_values.empty())
+ return true;
+ else
+ return (_imp->allowed_values.find(v) != _imp->allowed_values.end());
+}
+
Hook::Iterator
Hook::begin() const
{
@@ -78,3 +107,23 @@ Hook::name() const
return _imp->name;
}
+Hook::AllowedOutputValues::AllowedOutputValues()
+{
+}
+
+Hook::AllowedOutputValues::AllowedOutputValues(const AllowedOutputValues & other) :
+ allowed_values(other.allowed_values)
+{
+}
+
+Hook::AllowedOutputValues::~AllowedOutputValues()
+{
+}
+
+Hook::AllowedOutputValues
+Hook::AllowedOutputValues::operator() (const std::string & v) const
+{
+ AllowedOutputValues result(*this);
+ result.allowed_values.insert(v);
+ return result;
+}
diff --git a/paludis/hook.hh b/paludis/hook.hh
index ee0c1bd..ef8f44c 100644
--- a/paludis/hook.hh
+++ b/paludis/hook.hh
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2005, 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2007 Piotr Jaroszyński <peper@gentoo.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
@@ -22,12 +23,16 @@
#include <paludis/util/attributes.hh>
#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/compare.hh>
#include <utility>
#include <string>
+#include <set>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
namespace paludis
{
+#include <paludis/hook-se.hh>
+#include <paludis/hook-sr.hh>
/**
* Represents the data for an Environment hook call.
*
@@ -41,6 +46,10 @@ namespace paludis
///\name Basic operations
///\{
+ class AllowedOutputValues;
+
+ HookOutputDestination output_dest;
+
Hook(const std::string & name);
Hook(const Hook &);
@@ -53,6 +62,10 @@ namespace paludis
Hook operator() (const std::string & key, const std::string & value) const
PALUDIS_ATTRIBUTE((warn_unused_result));
+ Hook grab_output(const AllowedOutputValues & av);
+
+ bool validate_value(const std::string & value) const;
+
///\name Iterate over environment data
///\{
@@ -70,6 +83,24 @@ namespace paludis
std::string name() const
PALUDIS_ATTRIBUTE((warn_unused_result));
};
+
+ class PALUDIS_VISIBLE Hook::AllowedOutputValues
+ {
+ private:
+ friend class Hook;
+
+ std::set<std::string> allowed_values;
+
+ public:
+ AllowedOutputValues();
+
+ AllowedOutputValues(const AllowedOutputValues & other);
+
+ ~AllowedOutputValues();
+
+ AllowedOutputValues operator() (const std::string & v) const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
}
#endif
diff --git a/paludis/hook.se b/paludis/hook.se
new file mode 100644
index 0000000..3c8a7cf
--- /dev/null
+++ b/paludis/hook.se
@@ -0,0 +1,18 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et ft=sh :
+
+make_enum_HookOutputDestination()
+{
+ prefix hod
+
+ key hod_grab "grab"
+ key hod_stdout "stdout"
+
+ doxygen_comment << "END"
+ /**
+ * Determines what to do with hook's output.
+ *
+ * \ingroup grpenvironment
+ */
+END
+}
diff --git a/paludis/hook.sr b/paludis/hook.sr
new file mode 100644
index 0000000..57f5c02
--- /dev/null
+++ b/paludis/hook.sr
@@ -0,0 +1,22 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+make_class_HookResult()
+{
+ visible
+
+ key max_exit_status int
+ key output std::string
+
+ comparison_operators all max_exit_status
+
+ doxygen_comment << "END"
+ /**
+ * Result of a Hook.
+ *
+ * \see Hook
+ * \ingroup grpenvironment
+ * \nosubgrouping
+ */
+END
+}
diff --git a/paludis/hooker.cc b/paludis/hooker.cc
index 532606c..49973cb 100644
--- a/paludis/hooker.cc
+++ b/paludis/hooker.cc
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2007 Piotr Jaroszyński <peper@gentoo.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
@@ -50,7 +51,7 @@ namespace
{
}
- virtual int run(const Hook &) const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
+ virtual HookResult run(const Hook &) const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
virtual const FSEntry file_name() const = 0;
virtual void add_dependencies(const Hook &, DirectedGraph<std::string, int> &) = 0;
};
@@ -71,7 +72,7 @@ namespace
{
}
- virtual int run(const Hook &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual HookResult run(const Hook &) const PALUDIS_ATTRIBUTE((warn_unused_result));
virtual const FSEntry file_name() const
{
@@ -101,7 +102,7 @@ namespace
{
}
- virtual int run(const Hook &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual HookResult run(const Hook &) const PALUDIS_ATTRIBUTE((warn_unused_result));
virtual const FSEntry file_name() const
{
@@ -112,7 +113,7 @@ namespace
};
}
-int
+HookResult
BashHookFile::run(const Hook & hook) const
{
Context c("When running hook script '" + stringify(file_name()) + "' for hook '" + hook.name() + "':");
@@ -130,7 +131,7 @@ BashHookFile::run(const Hook & hook) const
.with_setenv("PALUDIS_REDUCED_UID", stringify(_env->reduced_uid()))
.with_setenv("PALUDIS_COMMAND", _env->paludis_command()));
- if (_run_prefixed)
+ if (hook.output_dest == hod_stdout && _run_prefixed)
cmd
.with_stdout_prefix(strip_trailing_string(file_name().basename(), ".bash") + "> ")
.with_stderr_prefix(strip_trailing_string(file_name().basename(), ".bash") + "> ");
@@ -138,7 +139,18 @@ BashHookFile::run(const Hook & hook) const
for (Hook::Iterator x(hook.begin()), x_end(hook.end()) ; x != x_end ; ++x)
cmd.with_setenv(x->first, x->second);
- int exit_status(run_command(cmd));
+ int exit_status(0);
+ std::string output("");
+ if (hook.output_dest == hod_grab)
+ {
+ PStream s(cmd);
+ output = strip_trailing(std::string((std::istreambuf_iterator<char>(s)), std::istreambuf_iterator<char>()),
+ " \t\n");
+ exit_status = s.exit_status();
+ }
+ else
+ exit_status = run_command(cmd);
+
if (0 == exit_status)
Log::get_instance()->message(ll_debug, lc_no_context, "Hook '" + stringify(file_name())
+ "' returned success '" + stringify(exit_status) + "'");
@@ -146,10 +158,10 @@ BashHookFile::run(const Hook & hook) const
Log::get_instance()->message(ll_warning, lc_no_context, "Hook '" + stringify(file_name())
+ "' returned failure '" + stringify(exit_status) + "'");
- return exit_status;
+ return HookResult(exit_status, output);
}
-int
+HookResult
FancyHookFile::run(const Hook & hook) const
{
Context c("When running hook script '" + stringify(file_name()) + "' for hook '" + hook.name() + "':");
@@ -170,7 +182,7 @@ FancyHookFile::run(const Hook & hook) const
.with_setenv("PALUDIS_REDUCED_UID", stringify(_env->reduced_uid()))
.with_setenv("PALUDIS_COMMAND", _env->paludis_command());
- if (_run_prefixed)
+ if (hook.output_dest == hod_stdout && _run_prefixed)
cmd
.with_stdout_prefix(strip_trailing_string(file_name().basename(), ".hook") + "> ")
.with_stderr_prefix(strip_trailing_string(file_name().basename(), ".hook") + "> ");
@@ -178,7 +190,18 @@ FancyHookFile::run(const Hook & hook) const
for (Hook::Iterator x(hook.begin()), x_end(hook.end()) ; x != x_end ; ++x)
cmd.with_setenv(x->first, x->second);
- int exit_status(run_command(cmd));
+ int exit_status(0);
+ std::string output("");
+ if (hook.output_dest == hod_grab)
+ {
+ PStream s(cmd);
+ output = strip_trailing(std::string((std::istreambuf_iterator<char>(s)), std::istreambuf_iterator<char>()),
+ " \t\n");
+ exit_status = s.exit_status();
+ }
+ else
+ exit_status = run_command(cmd);
+
if (0 == exit_status)
Log::get_instance()->message(ll_debug, lc_no_context, "Hook '" + stringify(file_name())
+ "' returned success '" + stringify(exit_status) + "'");
@@ -186,7 +209,7 @@ FancyHookFile::run(const Hook & hook) const
Log::get_instance()->message(ll_warning, lc_no_context, "Hook '" + stringify(file_name())
+ "' returned failure '" + stringify(exit_status) + "'");
- return exit_status;
+ return HookResult(exit_status, output);
}
void
@@ -289,20 +312,56 @@ Hooker::add_dir(const FSEntry & dir, const bool v)
_imp->dirs.push_back(std::make_pair(dir, v));
}
-int
+HookResult
Hooker::perform_hook(const Hook & hook) const
{
- int max_exit_status(0);
+ HookResult result(0, "");
Context context("When triggering hook '" + hook.name() + "':");
Log::get_instance()->message(ll_debug, lc_no_context, "Starting hook '" + hook.name() + "'");
/* repo hooks first */
- for (PackageDatabase::RepositoryIterator r(_imp->env->package_database()->begin_repositories()),
- r_end(_imp->env->package_database()->end_repositories()) ; r != r_end ; ++r)
- if ((*r)->hook_interface)
- max_exit_status = std::max(max_exit_status, ((*r)->hook_interface->perform_hook(hook)));
+ do
+ {
+ switch (hook.output_dest)
+ {
+ case hod_stdout:
+ for (PackageDatabase::RepositoryIterator r(_imp->env->package_database()->begin_repositories()),
+ r_end(_imp->env->package_database()->end_repositories()) ; r != r_end ; ++r)
+ if ((*r)->hook_interface)
+ result.max_exit_status = std::max(result.max_exit_status,
+ ((*r)->hook_interface->perform_hook(hook)).max_exit_status);
+ continue;
+
+ case hod_grab:
+ for (PackageDatabase::RepositoryIterator r(_imp->env->package_database()->begin_repositories()),
+ r_end(_imp->env->package_database()->end_repositories()) ; r != r_end ; ++r)
+ if ((*r)->hook_interface)
+ {
+ HookResult tmp((*r)->hook_interface->perform_hook(hook));
+ if (tmp > result)
+ result = tmp;
+ else if (! tmp.output.empty())
+ {
+ if (hook.validate_value(tmp.output))
+ {
+ if (result.max_exit_status == 0)
+ return tmp;
+ }
+ else
+ Log::get_instance()->message(ll_warning, lc_context)
+ << "Hook returned invalid output: '" << tmp.output << "'";
+ }
+ }
+ continue;
+
+ case last_hod:
+ ;
+ }
+ throw InternalError(PALUDIS_HERE, "Bad HookOutputDestination value '" + paludis::stringify(
+ static_cast<int>(hook.output_dest)));
+ } while(false);
/* file hooks, but only if necessary */
@@ -373,11 +432,46 @@ Hooker::perform_hook(const Hook & hook) const
if (! h->second.empty())
{
- for (std::list<std::tr1::shared_ptr<HookFile> >::const_iterator f(h->second.begin()), f_end(h->second.end()) ;
- f != f_end ; ++f)
- max_exit_status = std::max(max_exit_status, (*f)->run(hook));
+ do
+ {
+ switch (hook.output_dest)
+ {
+ case hod_stdout:
+ for (std::list<std::tr1::shared_ptr<HookFile> >::const_iterator f(h->second.begin()),
+ f_end(h->second.end()) ; f != f_end ; ++f)
+ result.max_exit_status = std::max(result.max_exit_status, (*f)->run(hook).max_exit_status);
+ continue;
+
+ case hod_grab:
+ for (std::list<std::tr1::shared_ptr<HookFile> >::const_iterator f(h->second.begin()),
+ f_end(h->second.end()) ; f != f_end ; ++f)
+ {
+ HookResult tmp((*f)->run(hook));
+ if (tmp > result)
+ result = tmp;
+ else if (! tmp.output.empty())
+ {
+ if (hook.validate_value(tmp.output))
+ {
+ if (result.max_exit_status == 0)
+ return tmp;
+ }
+ else
+ Log::get_instance()->message(ll_warning, lc_context)
+ << "Hook returned invalid output: '" << tmp.output << "'";
+ }
+ }
+ continue;
+
+ case last_hod:
+ ;
+ }
+ throw InternalError(PALUDIS_HERE, "Bad HookOutputDestination value '" + paludis::stringify(
+ static_cast<int>(hook.output_dest)));
+ } while(false);
+
}
- return max_exit_status;
+ return result;
}
diff --git a/paludis/hooker.hh b/paludis/hooker.hh
index 48c493c..2668ec8 100644
--- a/paludis/hooker.hh
+++ b/paludis/hooker.hh
@@ -28,6 +28,7 @@ namespace paludis
class FSEntry;
class Environment;
class Hook;
+ class HookResult;
/**
* Handles executing hooks for an Environment.
@@ -49,9 +50,9 @@ namespace paludis
///\}
/**
- * Perform a hook, return the highest exit status.
+ * Perform a hook, return HookResult.
*/
- int perform_hook(const Hook &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ HookResult perform_hook(const Hook &) const PALUDIS_ATTRIBUTE((warn_unused_result));
/**
* Add a new hook directory.
diff --git a/paludis/hooker_TEST.cc b/paludis/hooker_TEST.cc
index e04dd54..92e05ab 100644
--- a/paludis/hooker_TEST.cc
+++ b/paludis/hooker_TEST.cc
@@ -38,11 +38,19 @@ namespace test_cases
{
TestEnvironment env;
Hooker hooker(&env);
+ HookResult result(0, "");
hooker.add_dir(FSEntry("hooker_TEST_dir/"), false);
- TEST_CHECK_EQUAL(hooker.perform_hook(Hook("simple_hook")), 3);
- TEST_CHECK_EQUAL(hooker.perform_hook(Hook("fancy_hook")), 5);
- TEST_CHECK_EQUAL(hooker.perform_hook(Hook("several_hooks")), 7);
+ result = hooker.perform_hook(Hook("simple_hook"));
+ TEST_CHECK_EQUAL(result.max_exit_status, 3);
+ TEST_CHECK_EQUAL(result.output, "");
+ result = hooker.perform_hook(Hook("fancy_hook"));
+ TEST_CHECK_EQUAL(result.max_exit_status, 5);
+ TEST_CHECK_EQUAL(result.output, "");
+ result = hooker.perform_hook(Hook("several_hooks"));
+ TEST_CHECK_EQUAL(result.max_exit_status, 7);
+ TEST_CHECK_EQUAL(result.output, "");
+
}
} test_hooker;
@@ -58,7 +66,9 @@ namespace test_cases
FSEntry("hooker_TEST_dir/ordering.out").unlink();
hooker.add_dir(FSEntry("hooker_TEST_dir/"), false);
- TEST_CHECK_EQUAL(hooker.perform_hook(Hook("ordering")), 0);
+ HookResult result(hooker.perform_hook(Hook("ordering")));
+ TEST_CHECK_EQUAL(result.max_exit_status, 0);
+ TEST_CHECK_EQUAL(result.output, "");
std::ifstream f(stringify(FSEntry("hooker_TEST_dir/ordering.out")).c_str());
std::string line((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
@@ -79,13 +89,15 @@ namespace test_cases
FSEntry("hooker_TEST_dir/bad_hooks.out").unlink();
hooker.add_dir(FSEntry("hooker_TEST_dir/"), false);
- TEST_CHECK_EQUAL(hooker.perform_hook(Hook("bad_hooks")), 123);
+ HookResult result(hooker.perform_hook(Hook("bad_hooks")));
+ TEST_CHECK_EQUAL(result.max_exit_status, 123);
+ TEST_CHECK_EQUAL(result.output, "");
std::ifstream f(stringify(FSEntry("hooker_TEST_dir/bad_hooks.out")).c_str());
std::string line((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
TEST_CHECK_EQUAL(line, "one\nthree\n");
- }
+ }
} test_hooker_bad_hooks;
struct HookerCyclesTest : TestCase
@@ -100,7 +112,9 @@ namespace test_cases
FSEntry("hooker_TEST_dir/cycles.out").unlink();
hooker.add_dir(FSEntry("hooker_TEST_dir/"), false);
- TEST_CHECK_EQUAL(hooker.perform_hook(Hook("cycles")), 0);
+ HookResult result(hooker.perform_hook(Hook("cycles")));
+ TEST_CHECK_EQUAL(result.max_exit_status, 0);
+ TEST_CHECK_EQUAL(result.output, "");
std::ifstream f(stringify(FSEntry("hooker_TEST_dir/cycles.out")).c_str());
std::string line((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
@@ -108,5 +122,83 @@ namespace test_cases
TEST_CHECK_EQUAL(line, "b\na\ng\nf\ni\n");
}
} test_hooker_cycles;
+
+ struct HookerOutputTest : TestCase
+ {
+ HookerOutputTest() : TestCase("hooker output") { }
+
+ void run()
+ {
+ TestEnvironment env;
+ Hooker hooker(&env);
+ HookResult result(0, "");
+
+ FSEntry("hooker_TEST_dir/several_output.out").unlink();
+
+ hooker.add_dir(FSEntry("hooker_TEST_dir/"), false);
+
+ result = hooker.perform_hook(Hook("simple_hook_output")
+ .grab_output(Hook::AllowedOutputValues()("foo")));
+ TEST_CHECK_EQUAL(result.max_exit_status, 0);
+ TEST_CHECK_EQUAL(result.output, "foo");
+
+ result = hooker.perform_hook(Hook("fancy_hook_output")
+ .grab_output(Hook::AllowedOutputValues()("foo")));
+ TEST_CHECK_EQUAL(result.max_exit_status, 0);
+ TEST_CHECK_EQUAL(result.output, "foo");
+
+ result = hooker.perform_hook(Hook("several_hooks_output")
+ .grab_output(Hook::AllowedOutputValues()));
+ TEST_CHECK_EQUAL(result.max_exit_status, 0);
+ TEST_CHECK_EQUAL(result.output, "one");
+
+ result = hooker.perform_hook(Hook("several_hooks_output")
+ .grab_output(Hook::AllowedOutputValues()("one")));
+ TEST_CHECK_EQUAL(result.max_exit_status, 0);
+ TEST_CHECK_EQUAL(result.output, "one");
+
+ result = hooker.perform_hook(Hook("several_hooks_output")
+ .grab_output(Hook::AllowedOutputValues()("two")("three")));
+ TEST_CHECK_EQUAL(result.max_exit_status, 0);
+ TEST_CHECK_EQUAL(result.output, "two");
+
+ result = hooker.perform_hook(Hook("several_hooks_output")
+ .grab_output(Hook::AllowedOutputValues()("blah")));
+ TEST_CHECK_EQUAL(result.output, "");
+ TEST_CHECK_EQUAL(result.max_exit_status, 0);
+
+ std::ifstream f(stringify(FSEntry("hooker_TEST_dir/several_output.out")).c_str());
+ std::string line((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
+
+ TEST_CHECK_EQUAL(line, "one\none\none\ntwo\none\ntwo\nthree\n");
+
+ }
+ } test_hooker_output;
+
+ struct HookerBadOutputHooksTest : TestCase
+ {
+ HookerBadOutputHooksTest() : TestCase("hooker bad ouput hooks") { }
+
+ void run()
+ {
+ TestEnvironment env;
+ Hooker hooker(&env);
+
+ FSEntry("hooker_TEST_dir/several_output_bad.out").unlink();
+
+ hooker.add_dir(FSEntry("hooker_TEST_dir/"), false);
+
+ HookResult result(hooker.perform_hook(Hook("several_hooks_output_bad")
+ .grab_output(Hook::AllowedOutputValues())));
+ TEST_CHECK_EQUAL(result.output, "two");
+ TEST_CHECK_EQUAL(result.max_exit_status, 99);
+
+ std::ifstream f(stringify(FSEntry("hooker_TEST_dir/several_output_bad.out")).c_str());
+ std::string line((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
+
+ TEST_CHECK_EQUAL(line, "one\ntwo\nthree\n");
+ }
+ } test_hooker_bad_output_hooks;
+
}
diff --git a/paludis/hooker_TEST_setup.sh b/paludis/hooker_TEST_setup.sh
index b967c19..689da3f 100755
--- a/paludis/hooker_TEST_setup.sh
+++ b/paludis/hooker_TEST_setup.sh
@@ -10,6 +10,13 @@ exit 3
END
chmod +x simple_hook/one.bash
+mkdir simple_hook_output
+cat <<"END" > simple_hook_output/one.bash
+echo "foo"
+END
+chmod +x simple_hook_output/one.bash
+
+
mkdir fancy_hook
cat <<"END" > fancy_hook/one.hook
hook_run_fancy_hook() {
@@ -26,6 +33,23 @@ hook_after_fancy_hook() {
END
chmod +x fancy_hook/one.hook
+mkdir fancy_hook_output
+cat <<"END" > fancy_hook_output/one.hook
+hook_run_fancy_hook_output() {
+ echo foo
+}
+
+hook_depend_fancy_hook_output() {
+ echo
+}
+
+hook_after_fancy_hook_output() {
+ echo
+}
+END
+chmod +x fancy_hook_output/one.hook
+
+
mkdir several_hooks
cat <<"END" > several_hooks/one.hook
hook_run_several_hooks() {
@@ -60,6 +84,83 @@ hook_depend_several_hooks() {
END
chmod +x several_hooks/three.hook
+mkdir several_hooks_output
+cat <<"END" > several_hooks_output/one.hook
+hook_run_several_hooks_output() {
+ echo one
+ echo one >> hooker_TEST_dir/several_output.out
+}
+
+hook_depend_several_hooks_output() {
+ echo
+}
+END
+chmod +x several_hooks_output/one.hook
+
+cat <<"END" > several_hooks_output/two.hook
+hook_run_several_hooks_output() {
+ echo two
+ echo two >> hooker_TEST_dir/several_output.out
+}
+
+hook_depend_several_hooks_output() {
+ echo one
+}
+END
+chmod +x several_hooks_output/two.hook
+
+cat <<"END" > several_hooks_output/three.hook
+hook_run_several_hooks_output() {
+ echo three
+ echo three >> hooker_TEST_dir/several_output.out
+}
+
+hook_depend_several_hooks_output() {
+ echo two
+}
+END
+chmod +x several_hooks_output/three.hook
+
+mkdir several_hooks_output_bad
+cat <<"END" > several_hooks_output_bad/one.hook
+hook_run_several_hooks_output_bad() {
+ echo one
+ echo one >> hooker_TEST_dir/several_output_bad.out
+ return 1
+}
+
+hook_depend_several_hooks_output_bad() {
+ echo
+}
+END
+chmod +x several_hooks_output_bad/one.hook
+
+cat <<"END" > several_hooks_output_bad/two.hook
+hook_run_several_hooks_output_bad() {
+ echo two
+ echo two >> hooker_TEST_dir/several_output_bad.out
+ return 99
+}
+
+hook_depend_several_hooks_output_bad() {
+ echo one
+}
+END
+chmod +x several_hooks_output_bad/two.hook
+
+cat <<"END" > several_hooks_output_bad/three.hook
+hook_run_several_hooks_output_bad() {
+ echo three
+ echo three >> hooker_TEST_dir/several_output_bad.out
+ return 2
+}
+
+hook_depend_several_hooks_output_bad() {
+ echo two
+}
+END
+chmod +x several_hooks_output_bad/three.hook
+
mkdir ordering
cat <<"END" > ordering.common
hook_run_ordering() {
diff --git a/paludis/merger/merger.cc b/paludis/merger/merger.cc
index 2c7edfe..c66c8cd 100644
--- a/paludis/merger/merger.cc
+++ b/paludis/merger/merger.cc
@@ -59,7 +59,7 @@ Merger::check()
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_check_pre")
("INSTALL_SOURCE", stringify(_options.image))
- ("INSTALL_DESTINATION", stringify(_options.root)))))
+ ("INSTALL_DESTINATION", stringify(_options.root)))).max_exit_status)
make_check_fail();
do_dir_recursive(true, _options.image, _options.root);
@@ -67,7 +67,7 @@ Merger::check()
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_check_post")
("INSTALL_SOURCE", stringify(_options.image))
- ("INSTALL_DESTINATION", stringify(_options.root)))))
+ ("INSTALL_DESTINATION", stringify(_options.root)))).max_exit_status)
make_check_fail();
return _result;
@@ -103,7 +103,7 @@ Merger::merge()
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_pre")
("INSTALL_SOURCE", stringify(_options.image))
- ("INSTALL_DESTINATION", stringify(_options.root)))))
+ ("INSTALL_DESTINATION", stringify(_options.root)))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Merge of '" + stringify(_options.image) + "' to '" + stringify(_options.root) + "' pre hooks returned non-zero");
@@ -112,7 +112,7 @@ Merger::merge()
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_post")
("INSTALL_SOURCE", stringify(_options.image))
- ("INSTALL_DESTINATION", stringify(_options.root)))))
+ ("INSTALL_DESTINATION", stringify(_options.root)))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Merge of '" + stringify(_options.image) + "' to '" + stringify(_options.root) + "' post hooks returned non-zero");
}
@@ -195,7 +195,7 @@ Merger::on_file(bool is_check, const FSEntry & src, const FSEntry & dst)
0 != _options.environment->perform_hook(extend_hook(
Hook("merger_check_file_pre")
("INSTALL_SOURCE", stringify(src))
- ("INSTALL_DESTINATION", stringify(dst / src.basename())))))
+ ("INSTALL_DESTINATION", stringify(dst / src.basename())))).max_exit_status)
make_check_fail();
do
@@ -233,7 +233,7 @@ Merger::on_file(bool is_check, const FSEntry & src, const FSEntry & dst)
0 != _options.environment->perform_hook(extend_hook(
Hook("merger_check_file_post")
("INSTALL_SOURCE", stringify(src))
- ("INSTALL_DESTINATION", stringify(dst / src.basename())))))
+ ("INSTALL_DESTINATION", stringify(dst / src.basename())))).max_exit_status)
make_check_fail();
}
@@ -248,7 +248,7 @@ Merger::on_dir(bool is_check, const FSEntry & src, const FSEntry & dst)
0 != _options.environment->perform_hook(extend_hook(
Hook("merger_check_dir_pre")
("INSTALL_SOURCE", stringify(src))
- ("INSTALL_DESTINATION", stringify(dst / src.basename())))))
+ ("INSTALL_DESTINATION", stringify(dst / src.basename())))).max_exit_status)
make_check_fail();
do
@@ -287,7 +287,7 @@ Merger::on_dir(bool is_check, const FSEntry & src, const FSEntry & dst)
0 != _options.environment->perform_hook(extend_hook(
Hook("merger_check_dir_post")
("INSTALL_SOURCE", stringify(src))
- ("INSTALL_DESTINATION", stringify(dst / src.basename())))))
+ ("INSTALL_DESTINATION", stringify(dst / src.basename())))).max_exit_status)
make_check_fail();
}
@@ -302,7 +302,7 @@ Merger::on_sym(bool is_check, const FSEntry & src, const FSEntry & dst)
0 != _options.environment->perform_hook(extend_hook(
Hook("merger_check_sym_post")
("INSTALL_SOURCE", stringify(src))
- ("INSTALL_DESTINATION", stringify(dst / src.basename())))))
+ ("INSTALL_DESTINATION", stringify(dst / src.basename())))).max_exit_status)
make_check_fail();
do
@@ -340,7 +340,7 @@ Merger::on_sym(bool is_check, const FSEntry & src, const FSEntry & dst)
0 != _options.environment->perform_hook(extend_hook(
Hook("merger_check_sym_post")
("INSTALL_SOURCE", stringify(src))
- ("INSTALL_DESTINATION", stringify(dst / src.basename())))))
+ ("INSTALL_DESTINATION", stringify(dst / src.basename())))).max_exit_status)
make_check_fail();
}
@@ -543,7 +543,7 @@ Merger::install_file(const FSEntry & src, const FSEntry & dst_dir, const std::st
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_file_pre")
("INSTALL_SOURCE", stringify(src))
- ("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))))
+ ("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Merge of '" + stringify(src) + "' to '" + stringify(dst_dir) + "' pre hooks returned non-zero");
@@ -575,7 +575,7 @@ Merger::install_file(const FSEntry & src, const FSEntry & dst_dir, const std::st
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_file_post")
("INSTALL_SOURCE", stringify(src))
- ("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))))
+ ("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Merge of '" + stringify(src) + "' to '" + stringify(dst_dir) + "' post hooks returned non-zero");
}
@@ -588,7 +588,7 @@ Merger::install_dir(const FSEntry & src, const FSEntry & dst_dir)
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_dir_pre")
("INSTALL_SOURCE", stringify(src))
- ("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))))
+ ("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Merge of '" + stringify(src) + "' to '" + stringify(dst_dir) + "' pre hooks returned non-zero");
@@ -606,7 +606,7 @@ Merger::install_dir(const FSEntry & src, const FSEntry & dst_dir)
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_dir_post")
("INSTALL_SOURCE", stringify(src))
- ("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))))
+ ("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Merge of '" + stringify(src) + "' to '" + stringify(dst_dir) + "' post hooks returned non-zero");
}
@@ -619,7 +619,7 @@ Merger::install_sym(const FSEntry & src, const FSEntry & dst_dir)
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_sym_pre")
("INSTALL_SOURCE", stringify(src))
- ("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))))
+ ("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Merge of '" + stringify(src) + "' to '" + stringify(dst_dir) + "' pre hooks returned non-zero");
@@ -630,7 +630,7 @@ Merger::install_sym(const FSEntry & src, const FSEntry & dst_dir)
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_install_sym_post")
("INSTALL_SOURCE", stringify(src))
- ("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))))
+ ("INSTALL_DESTINATION", stringify(dst_dir / src.basename())))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Merge of '" + stringify(src) + "' to '" + stringify(dst_dir) + "' post hooks returned non-zero");
}
@@ -640,7 +640,7 @@ Merger::unlink_file(FSEntry d)
{
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_unlink_file_pre")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Unmerge of '" + stringify(d) + "' pre hooks returned non-zero");
@@ -658,7 +658,7 @@ Merger::unlink_file(FSEntry d)
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_unlink_file_post")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Unmerge of '" + stringify(d) + "' post hooks returned non-zero");
}
@@ -668,7 +668,7 @@ Merger::unlink_sym(FSEntry d)
{
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_unlink_sym_pre")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Unmerge of '" + stringify(d) + "' pre hooks returned non-zero");
@@ -676,7 +676,7 @@ Merger::unlink_sym(FSEntry d)
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_unlink_sym_post")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Unmerge of '" + stringify(d) + "' post hooks returned non-zero");
}
@@ -686,7 +686,7 @@ Merger::unlink_dir(FSEntry d)
{
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_unlink_dir_pre")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Unmerge of '" + stringify(d) + "' pre hooks returned non-zero");
@@ -694,7 +694,7 @@ Merger::unlink_dir(FSEntry d)
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_unlink_dir_post")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Unmerge of '" + stringify(d) + "' post hooks returned non-zero");
}
@@ -704,7 +704,7 @@ Merger::unlink_misc(FSEntry d)
{
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_unlink_misc_pre")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Unmerge of '" + stringify(d) + "' pre hooks returned non-zero");
@@ -712,7 +712,7 @@ Merger::unlink_misc(FSEntry d)
if (0 != _options.environment->perform_hook(extend_hook(
Hook("merger_unlink_misc_post")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
Log::get_instance()->message(ll_warning, lc_context,
"Unmerge of '" + stringify(d) + "' post hooks returned non-zero");
}
diff --git a/paludis/merger/unmerger.cc b/paludis/merger/unmerger.cc
index 5d90c09..8daf703 100644
--- a/paludis/merger/unmerger.cc
+++ b/paludis/merger/unmerger.cc
@@ -48,7 +48,7 @@ Unmerger::unlink_file(FSEntry d)
{
if (0 != _options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_file_pre")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
throw UnmergerError("Unmerge of '" + stringify(d) + "' aborted by hook");
if (d.is_regular_file())
@@ -65,7 +65,7 @@ Unmerger::unlink_file(FSEntry d)
if (0 != _options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_file_post")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
throw UnmergerError("Unmerge of '" + stringify(d) + "' aborted by hook");
}
@@ -74,14 +74,14 @@ Unmerger::unlink_sym(FSEntry d)
{
if (0 != _options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_sym_pre")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
throw UnmergerError("Unmerge of '" + stringify(d) + "' aborted by hook");
d.unlink();
if (0 != _options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_sym_post")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
throw UnmergerError("Unmerge of '" + stringify(d) + "' aborted by hook");
}
@@ -90,14 +90,14 @@ Unmerger::unlink_dir(FSEntry d)
{
if (0 != _options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_dir_pre")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
throw UnmergerError("Unmerge of '" + stringify(d) + "' aborted by hook");
d.rmdir();
if (0 != _options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_dir_post")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
throw UnmergerError("Unmerge of '" + stringify(d) + "' aborted by hook");
}
@@ -106,14 +106,14 @@ Unmerger::unlink_misc(FSEntry d)
{
if (0 != _options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_misc_pre")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
throw UnmergerError("Unmerge of '" + stringify(d) + "' aborted by hook");
d.unlink();
if (0 != _options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_misc_post")
- ("UNLINK_TARGET", stringify(d)))))
+ ("UNLINK_TARGET", stringify(d)))).max_exit_status)
throw UnmergerError("Unmerge of '" + stringify(d) + "' aborted by hook");
}
diff --git a/paludis/repositories/gentoo/portage_repository.cc b/paludis/repositories/gentoo/portage_repository.cc
index 3404fd8..ea14efc 100644
--- a/paludis/repositories/gentoo/portage_repository.cc
+++ b/paludis/repositories/gentoo/portage_repository.cc
@@ -1260,7 +1260,7 @@ PortageRepository::merge(const MergeOptions & o)
_imp->entries_ptr->merge(o);
}
-int
+HookResult
PortageRepository::perform_hook(const Hook & hook) const
{
Context context("When performing hook '" + stringify(hook.name()) + "' for repository '"
@@ -1271,6 +1271,6 @@ PortageRepository::perform_hook(const Hook & hook) const
|| hook.name() == "uninstall_all_post")
update_news();
- return 0;
+ return HookResult(0, "");
}
diff --git a/paludis/repositories/gentoo/portage_repository.hh b/paludis/repositories/gentoo/portage_repository.hh
index 4048d88..416e582 100644
--- a/paludis/repositories/gentoo/portage_repository.hh
+++ b/paludis/repositories/gentoo/portage_repository.hh
@@ -187,7 +187,7 @@ namespace paludis
///\}
- int perform_hook(const Hook &) const
+ HookResult perform_hook(const Hook &) const
PALUDIS_ATTRIBUTE((warn_unused_result));
/**
diff --git a/paludis/repositories/gentoo/vdb_repository.cc b/paludis/repositories/gentoo/vdb_repository.cc
index 0978e19..55acd24 100644
--- a/paludis/repositories/gentoo/vdb_repository.cc
+++ b/paludis/repositories/gentoo/vdb_repository.cc
@@ -1580,12 +1580,12 @@ VDBRepository::merge(const MergeOptions & m)
post_merge_command();
}
-int
+HookResult
VDBRepository::perform_hook(const Hook & hook) const
{
Context context("When performing hook '" + stringify(hook.name()) + "' for repository '"
+ stringify(name()) + "':");
- return 0;
+ return HookResult(0, "");
}
diff --git a/paludis/repositories/gentoo/vdb_repository.hh b/paludis/repositories/gentoo/vdb_repository.hh
index 77052aa..33adcd9 100644
--- a/paludis/repositories/gentoo/vdb_repository.hh
+++ b/paludis/repositories/gentoo/vdb_repository.hh
@@ -181,7 +181,7 @@ namespace paludis
virtual FSEntry root() const;
- int perform_hook(const Hook &) const
+ HookResult perform_hook(const Hook &) const
PALUDIS_ATTRIBUTE((warn_unused_result));
};
diff --git a/paludis/repositories/gentoo/vdb_unmerger.cc b/paludis/repositories/gentoo/vdb_unmerger.cc
index 4f61d5b..e0195a8 100644
--- a/paludis/repositories/gentoo/vdb_unmerger.cc
+++ b/paludis/repositories/gentoo/vdb_unmerger.cc
@@ -110,7 +110,7 @@ VDBUnmerger::unmerge()
if (0 != _imp->options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_pre")
- ("UNLINK_TARGET", stringify(_imp->options.root)))))
+ ("UNLINK_TARGET", stringify(_imp->options.root)))).max_exit_status)
throw UnmergerError("Unmerge of '" + stringify(_imp->options.root) + "' aborted by hook");
unmerge_non_directories(lines.begin(), lines.end());
@@ -118,7 +118,7 @@ VDBUnmerger::unmerge()
if (0 != _imp->options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_post")
- ("UNLINK_TARGET", stringify(_imp->options.root)))))
+ ("UNLINK_TARGET", stringify(_imp->options.root)))).max_exit_status)
throw UnmergerError("Unmerge of '" + stringify(_imp->options.root) + "' aborted by hook");
}
diff --git a/paludis/repositories/virtuals/installed_virtuals_repository.cc b/paludis/repositories/virtuals/installed_virtuals_repository.cc
index 8617bbe..41099c3 100644
--- a/paludis/repositories/virtuals/installed_virtuals_repository.cc
+++ b/paludis/repositories/virtuals/installed_virtuals_repository.cc
@@ -322,12 +322,12 @@ InstalledVirtualsRepository::root() const
return _imp->root;
}
-int
+HookResult
InstalledVirtualsRepository::perform_hook(const Hook & hook) const
{
Context context("When performing hook '" + stringify(hook.name()) + "' for repository '"
+ stringify(name()) + "':");
- return 0;
+ return HookResult(0, "");
}
diff --git a/paludis/repositories/virtuals/installed_virtuals_repository.hh b/paludis/repositories/virtuals/installed_virtuals_repository.hh
index b21fdb7..bb6cb13 100644
--- a/paludis/repositories/virtuals/installed_virtuals_repository.hh
+++ b/paludis/repositories/virtuals/installed_virtuals_repository.hh
@@ -92,7 +92,7 @@ namespace paludis
virtual FSEntry root() const;
- int perform_hook(const Hook &) const
+ HookResult perform_hook(const Hook &) const
PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/paludis/repository-fwd.hh b/paludis/repository-fwd.hh
index 7eaf14b..882fb44 100644
--- a/paludis/repository-fwd.hh
+++ b/paludis/repository-fwd.hh
@@ -29,6 +29,7 @@ namespace paludis
class RepositoryNameCache;
class PortageRepositoryProfile;
class Hook;
+ class HookResult;
class Repository;
class RepositoryInstallableInterface;
diff --git a/paludis/repository.hh b/paludis/repository.hh
index ca04583..8a87a4e 100644
--- a/paludis/repository.hh
+++ b/paludis/repository.hh
@@ -1143,9 +1143,9 @@ namespace paludis
{
public:
/**
- * Perform a hook, and return the highest exit status.
+ * Perform a hook.
*/
- virtual int perform_hook(const Hook & hook) const
+ virtual HookResult perform_hook(const Hook & hook) const
PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
virtual ~RepositoryHookInterface();
diff --git a/paludis/tasks/install_task.cc b/paludis/tasks/install_task.cc
index cafce67..660ddad 100644
--- a/paludis/tasks/install_task.cc
+++ b/paludis/tasks/install_task.cc
@@ -161,7 +161,7 @@ InstallTask::execute()
/* we're about to display our task list */
if (_imp->pretend &&
0 != perform_hook(Hook("install_pretend_pre")("TARGETS", join(_imp->raw_targets.begin(),
- _imp->raw_targets.end(), " "))))
+ _imp->raw_targets.end(), " "))).max_exit_status)
throw PackageInstallActionError("Pretend install aborted by hook");
on_display_merge_list_pre();
@@ -173,7 +173,7 @@ InstallTask::execute()
if (_imp->pretend &&
0 != perform_hook(Hook("install_pretend_display_item_pre")
("TARGET", stringify(dep->package))
- ("KIND", stringify(dep->kind))))
+ ("KIND", stringify(dep->kind))).max_exit_status)
throw PackageInstallActionError("Pretend install aborted by hook");
_imp->current_dep_list_entry = dep;
@@ -182,7 +182,7 @@ InstallTask::execute()
if (_imp->pretend &&
0 != perform_hook(Hook("install_pretend_display_item_post")
("TARGET", stringify(dep->package))
- ("KIND", stringify(dep->kind))))
+ ("KIND", stringify(dep->kind))).max_exit_status)
throw PackageInstallActionError("Pretend install aborted by hook");
}
@@ -192,7 +192,7 @@ InstallTask::execute()
if (_imp->pretend)
{
if (0 != perform_hook(Hook("install_pretend_post")("TARGETS", join(
- _imp->raw_targets.begin(), _imp->raw_targets.end(), " "))))
+ _imp->raw_targets.begin(), _imp->raw_targets.end(), " "))).max_exit_status)
throw PackageInstallActionError("Pretend install aborted by hook");
return;
}
@@ -207,7 +207,7 @@ InstallTask::execute()
if (_imp->install_options.fetch_only)
{
if (0 != perform_hook(Hook("fetch_all_pre")("TARGETS", join(
- _imp->raw_targets.begin(), _imp->raw_targets.end(), " "))))
+ _imp->raw_targets.begin(), _imp->raw_targets.end(), " "))).max_exit_status)
throw PackageInstallActionError("Fetch aborted by hook");
on_fetch_all_pre();
}
@@ -225,7 +225,7 @@ InstallTask::execute()
if (0 != perform_hook(Hook("install_all_pre")
("TARGETS", join(_imp->raw_targets.begin(), _imp->raw_targets.end(), " "))
- ("PALUDIS_NO_LIVE_DESTINATION", any_live_destination ? "" : "yes")))
+ ("PALUDIS_NO_LIVE_DESTINATION", any_live_destination ? "" : "yes")).max_exit_status)
throw PackageInstallActionError("Install aborted by hook");
on_install_all_pre();
}
@@ -262,7 +262,7 @@ InstallTask::execute()
{
if (0 != perform_hook(Hook("fetch_pre")
("TARGET", cpvr)
- ("X_OF_Y", stringify(x) + " of " + stringify(y))))
+ ("X_OF_Y", stringify(x) + " of " + stringify(y))).max_exit_status)
throw PackageInstallActionError("Fetch of '" + cpvr + "' aborted by hook");
on_fetch_pre(*dep);
}
@@ -271,7 +271,7 @@ InstallTask::execute()
if (0 != perform_hook(Hook("install_pre")
("TARGET", cpvr)
("X_OF_Y", stringify(x) + " of " + stringify(y))
- ("PALUDIS_NO_LIVE_DESTINATION", live_destination ? "" : "yes")))
+ ("PALUDIS_NO_LIVE_DESTINATION", live_destination ? "" : "yes")).max_exit_status)
throw PackageInstallActionError("Install of '" + cpvr + "' aborted by hook");
on_install_pre(*dep);
}
@@ -291,7 +291,7 @@ InstallTask::execute()
catch (const PackageInstallActionError & e)
{
on_install_fail(*dep);
- int PALUDIS_ATTRIBUTE((unused)) dummy(perform_hook(Hook("install_fail")("TARGET", cpvr)("MESSAGE", e.message())));
+ HookResult PALUDIS_ATTRIBUTE((unused)) dummy(perform_hook(Hook("install_fail")("TARGET", cpvr)("MESSAGE", e.message())));
throw;
}
@@ -301,7 +301,7 @@ InstallTask::execute()
on_fetch_post(*dep);
if (0 != perform_hook(Hook("fetch_post")
("TARGET", cpvr)
- ("X_OF_Y", stringify(x) + " of " + stringify(y))))
+ ("X_OF_Y", stringify(x) + " of " + stringify(y))).max_exit_status)
throw PackageInstallActionError("Fetch of '" + cpvr + "' aborted by hook");
}
else
@@ -310,7 +310,7 @@ InstallTask::execute()
if (0 != perform_hook(Hook("install_post")
("TARGET", cpvr)
("X_OF_Y", stringify(x) + " of " + stringify(y))
- ("PALUDIS_NO_LIVE_DESTINATION", live_destination ? "" : "yes")))
+ ("PALUDIS_NO_LIVE_DESTINATION", live_destination ? "" : "yes")).max_exit_status)
throw PackageInstallActionError("Install of '" + cpvr + "' aborted by hook");
}
@@ -363,7 +363,7 @@ InstallTask::execute()
else
{
if (0 != perform_hook(Hook("clean_all_pre")("TARGETS", join(
- clean_list.begin(), clean_list.end(), " "))))
+ clean_list.begin(), clean_list.end(), " "))).max_exit_status)
throw PackageInstallActionError("Clean aborted by hook");
on_clean_all_pre(*dep, clean_list);
@@ -372,7 +372,7 @@ InstallTask::execute()
{
/* clean one item */
if (0 != perform_hook(Hook("clean_pre")("TARGET", stringify(*c))
- ("X_OF_Y", stringify(x) + " of " + stringify(y))))
+ ("X_OF_Y", stringify(x) + " of " + stringify(y))).max_exit_status)
throw PackageInstallActionError("Clean of '" + cpvr + "' aborted by hook");
on_clean_pre(*dep, *c);
@@ -389,19 +389,19 @@ InstallTask::execute()
catch (const PackageUninstallActionError & e)
{
on_clean_fail(*dep, *c);
- int PALUDIS_ATTRIBUTE((unused)) dummy(perform_hook(Hook("clean_fail")("TARGET", stringify(*c))("MESSAGE", e.message())));
+ HookResult PALUDIS_ATTRIBUTE((unused)) dummy(perform_hook(Hook("clean_fail")("TARGET", stringify(*c))("MESSAGE", e.message())));
throw;
}
on_clean_post(*dep, *c);
if (0 != perform_hook(Hook("clean_post")("TARGET", stringify(*c))
- ("X_OF_Y", stringify(x) + " of " + stringify(y))))
+ ("X_OF_Y", stringify(x) + " of " + stringify(y))).max_exit_status)
throw PackageInstallActionError("Clean of '" + cpvr + "' aborted by hook");
}
/* we're done cleaning */
if (0 != perform_hook(Hook("clean_all_post")("TARGETS", join(
- clean_list.begin(), clean_list.end(), " "))))
+ clean_list.begin(), clean_list.end(), " "))).max_exit_status)
throw PackageInstallActionError("Clean aborted by hook");
on_clean_all_post(*dep, clean_list);
}
@@ -457,14 +457,14 @@ InstallTask::execute()
{
on_fetch_all_post();
if (0 != perform_hook(Hook("fetch_all_post")("TARGETS", join(
- _imp->raw_targets.begin(), _imp->raw_targets.end(), " "))))
+ _imp->raw_targets.begin(), _imp->raw_targets.end(), " "))).max_exit_status)
throw PackageInstallActionError("Fetch aborted by hook");
}
else
{
on_install_all_post();
if (0 != perform_hook(Hook("install_all_post")("TARGETS", join(
- _imp->raw_targets.begin(), _imp->raw_targets.end(), " "))))
+ _imp->raw_targets.begin(), _imp->raw_targets.end(), " "))).max_exit_status)
throw PackageInstallActionError("Install aborted by hook");
}
}
@@ -565,7 +565,7 @@ InstallTask::set_safe_resume(const bool value)
_imp->install_options.safe_resume = value;
}
-int
+HookResult
InstallTask::perform_hook(const Hook & hook) const
{
return _imp->env->perform_hook(hook);
diff --git a/paludis/tasks/install_task.hh b/paludis/tasks/install_task.hh
index 84639b7..4096d3a 100644
--- a/paludis/tasks/install_task.hh
+++ b/paludis/tasks/install_task.hh
@@ -171,7 +171,7 @@ namespace paludis
/**
* Perform a hook. By default, delegates to environment.
*/
- virtual int perform_hook(const Hook &) const
+ virtual HookResult perform_hook(const Hook &) const
PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/paludis/tasks/sync_task.cc b/paludis/tasks/sync_task.cc
index cfae99d..38dd94c 100644
--- a/paludis/tasks/sync_task.cc
+++ b/paludis/tasks/sync_task.cc
@@ -69,7 +69,7 @@ SyncTask::execute()
if (0 !=
_imp->env->perform_hook(Hook("sync_all_pre")("TARGETS", join(_imp->targets.begin(),
- _imp->targets.end(), " "))))
+ _imp->targets.end(), " "))).max_exit_status)
throw SyncFailedError("Sync aborted by hook");
on_sync_all_pre();
@@ -84,7 +84,7 @@ SyncTask::execute()
{
if (0 !=
_imp->env->perform_hook(Hook("sync_pre")("TARGET", stringify(*r))
- ("X_OF_Y", stringify(x) + " of " + stringify(y))))
+ ("X_OF_Y", stringify(x) + " of " + stringify(y))).max_exit_status)
throw SyncFailedError("Sync of '" + stringify(*r) + "' aborted by hook");
on_sync_pre(*r);
@@ -98,12 +98,12 @@ SyncTask::execute()
on_sync_post(*r);
if (0 !=
_imp->env->perform_hook(Hook("sync_post")("TARGET", stringify(*r))
- ("X_OF_Y", stringify(x) + " of " + stringify(y))))
+ ("X_OF_Y", stringify(x) + " of " + stringify(y))).max_exit_status)
throw SyncFailedError("Sync of '" + stringify(*r) + "' aborted by hook");
}
catch (const SyncFailedError & e)
{
- int PALUDIS_ATTRIBUTE((unused)) dummy(_imp->env->perform_hook(Hook("sync_fail")("TARGET", stringify(*r))
+ HookResult PALUDIS_ATTRIBUTE((unused)) dummy(_imp->env->perform_hook(Hook("sync_fail")("TARGET", stringify(*r))
("X_OF_Y", stringify(x) + " of " + stringify(y))));
on_sync_fail(*r, e);
}
@@ -112,7 +112,7 @@ SyncTask::execute()
on_sync_all_post();
if (0 !=
_imp->env->perform_hook(Hook("sync_all_post")("TARGETS", join(_imp->targets.begin(),
- _imp->targets.end(), " "))))
+ _imp->targets.end(), " "))).max_exit_status)
throw SyncFailedError("Sync aborted by hook");
}
diff --git a/paludis/tasks/uninstall_task.cc b/paludis/tasks/uninstall_task.cc
index 4226110..73d41c0 100644
--- a/paludis/tasks/uninstall_task.cc
+++ b/paludis/tasks/uninstall_task.cc
@@ -268,7 +268,7 @@ UninstallTask::execute()
if (0 !=
_imp->env->perform_hook(Hook("uninstall_all_pre")("TARGETS", join(_imp->raw_targets.begin(),
- _imp->raw_targets.end(), " "))))
+ _imp->raw_targets.end(), " "))).max_exit_status)
throw PackageUninstallActionError("Uninstall aborted by hook");
on_uninstall_all_pre();
@@ -287,7 +287,7 @@ UninstallTask::execute()
if (0 !=
_imp->env->perform_hook(Hook("uninstall_pre")("TARGET", cpvr)
- ("X_OF_Y", stringify(x) + " of " + stringify(y))))
+ ("X_OF_Y", stringify(x) + " of " + stringify(y))).max_exit_status)
throw PackageUninstallActionError("Uninstall of '" + cpvr + "' aborted by hook");
on_uninstall_pre(*i);
@@ -303,21 +303,21 @@ UninstallTask::execute()
}
catch (const PackageUninstallActionError & e)
{
- int PALUDIS_ATTRIBUTE((unused)) dummy(_imp->env->perform_hook(Hook("uninstall_fail")("TARGET", cpvr)("MESSAGE", e.message())));
+ HookResult PALUDIS_ATTRIBUTE((unused)) dummy(_imp->env->perform_hook(Hook("uninstall_fail")("TARGET", cpvr)("MESSAGE", e.message())));
throw;
}
on_uninstall_post(*i);
if (0 !=
_imp->env->perform_hook(Hook("uninstall_post")("TARGET", cpvr)
- ("X_OF_Y", stringify(x) + " of " + stringify(y))))
+ ("X_OF_Y", stringify(x) + " of " + stringify(y))).max_exit_status)
throw PackageUninstallActionError("Uninstall of '" + cpvr + "' aborted by hook");
}
on_uninstall_all_post();
if (0 !=
_imp->env->perform_hook(Hook("uninstall_all_post")("TARGETS", join(_imp->raw_targets.begin(),
- _imp->raw_targets.end(), " "))))
+ _imp->raw_targets.end(), " "))).max_exit_status)
throw PackageUninstallActionError("Uninstall aborted by hook");
}
diff --git a/src/clients/paludis/install.cc b/src/clients/paludis/install.cc
index 63c78aa..21b546f 100644
--- a/src/clients/paludis/install.cc
+++ b/src/clients/paludis/install.cc
@@ -235,7 +235,7 @@ namespace
execl("/bin/sh", "sh", "-c", resume_command.c_str(), static_cast<const char *>(0));
}
- virtual int perform_hook(const Hook & hook) const
+ virtual HookResult perform_hook(const Hook & hook) const
{
return ConsoleInstallTask::perform_hook(hook("RESUME_COMMAND", make_resume_command(
_env, *this, false)));