aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-04-24 07:34:00 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-04-24 07:34:00 +0000
commitf2049330860ccf9e3643704b2394177eca9ea2d8 (patch)
tree82c55b76cc850418e4c6c6cf5790861fd1b55109
parent3cb728757c97f47691a57fadf6523c8ba648e3fc (diff)
downloadpaludis-f2049330860ccf9e3643704b2394177eca9ea2d8.tar.gz
paludis-f2049330860ccf9e3643704b2394177eca9ea2d8.tar.xz
Rename depend ebuild action to metadata and remove updateenv action. Add a hooks framework. Use hooks for eselect env update, updating GNU info directories and checking for config file updates. Fix log output when redirected. Add docs note on hooks.
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac1
-rw-r--r--doc/doc_portage_differences.doxygen4
-rw-r--r--ebuild/Makefile.am15
-rw-r--r--ebuild/builtin_merge.bash1
-rw-r--r--ebuild/builtin_metadata.bash (renamed from ebuild/depend.bash)2
-rwxr-xr-xebuild/ebuild.bash33
-rw-r--r--ebuild/echo_functions.bash2
-rw-r--r--hooks/Makefile.am51
-rwxr-xr-x[-rw-r--r--]hooks/eselect_env_update.bash (renamed from ebuild/builtin_updateenv.bash)26
-rwxr-xr-xhooks/find_config_updates.bash42
-rwxr-xr-xhooks/gnu_info_index.bash82
-rw-r--r--paludis/Makefile.am.m41
-rw-r--r--paludis/default_config.cc3
-rw-r--r--paludis/default_config.hh19
-rw-r--r--paludis/default_environment.cc103
-rw-r--r--paludis/default_environment.hh4
-rw-r--r--paludis/ebuild.cc3
-rw-r--r--paludis/environment.hh10
-rw-r--r--paludis/test_environment.hh9
-rw-r--r--src/install.cc26
-rw-r--r--src/sync.cc4
-rw-r--r--src/uninstall.cc4
23 files changed, 408 insertions, 39 deletions
diff --git a/Makefile.am b/Makefile.am
index 7330161..765f19e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,7 +3,7 @@ MAINTAINERCLEANFILES = Makefile.in configure config/* aclocal.m4 \
config.h config.h.in INSTALL COPYING
AUTOMAKE_OPTIONS = dist-bzip2 no-dist-gzip std-options
EXTRA_DIST = autogen.bash
-SUBDIRS = misc test paludis ebuild src doc
+SUBDIRS = misc test paludis ebuild src doc hooks
doxygen :
$(MAKE) -C doc doxygen
diff --git a/configure.ac b/configure.ac
index e490545..6d91d88 100644
--- a/configure.ac
+++ b/configure.ac
@@ -341,6 +341,7 @@ AC_OUTPUT(
ebuild/Makefile
ebuild/digests/Makefile
ebuild/utils/Makefile
+ hooks/Makefile
misc/Makefile
misc/svn-version-filter-data.bash
paludis/Makefile
diff --git a/doc/doc_portage_differences.doxygen b/doc/doc_portage_differences.doxygen
index 2d22585..7012fde 100644
--- a/doc/doc_portage_differences.doxygen
+++ b/doc/doc_portage_differences.doxygen
@@ -29,6 +29,8 @@ would be relevant if it were:
- Licence filtering.
+- Hook scripts, for running code after a certain action occurs.
+
\section PortageDifferencesEbuildDeveloper For the Ebuild Developer
As well as the end user advantages, ebuild authors will benefit from:
@@ -50,6 +52,8 @@ As well as the end user advantages, ebuild authors will benefit from:
- Multiple inheritance for profiles.
+- Ability to install hook scripts.
+
\section PortageDifferencesProgrammer For the Programmer
- Proper library / interface separation.
diff --git a/ebuild/Makefile.am b/ebuild/Makefile.am
index 34cdfd0..14d7bc1 100644
--- a/ebuild/Makefile.am
+++ b/ebuild/Makefile.am
@@ -6,7 +6,13 @@ libexecprogdir = $(libexecdir)/paludis/
libexecprog_SCRIPTS = \
build_functions.bash \
- depend.bash \
+ builtin_fetch.bash \
+ builtin_init.bash \
+ builtin_merge.bash \
+ builtin_metadata.bash \
+ builtin_strip.bash \
+ builtin_tidyup.bash \
+ builtin_unmerge.bash \
ebuild.bash \
echo_functions.bash \
eclass_functions.bash \
@@ -14,7 +20,6 @@ libexecprog_SCRIPTS = \
list_functions.bash \
multilib_functions.bash \
pkg_config.bash \
- builtin_init.bash \
pkg_nofetch.bash \
pkg_postinst.bash \
pkg_postrm.bash \
@@ -24,12 +29,6 @@ libexecprog_SCRIPTS = \
portage_stubs.bash \
sandbox_stubs.bash \
src_compile.bash \
- builtin_fetch.bash \
- builtin_merge.bash \
- builtin_unmerge.bash \
- builtin_tidyup.bash \
- builtin_strip.bash \
- builtin_updateenv.bash \
src_install.bash \
src_test.bash \
src_unpack.bash \
diff --git a/ebuild/builtin_merge.bash b/ebuild/builtin_merge.bash
index 0c5d58e..03cf8fd 100644
--- a/ebuild/builtin_merge.bash
+++ b/ebuild/builtin_merge.bash
@@ -28,6 +28,7 @@ builtin_merge()
local dbdir="${ROOT%/}"/var/db/pkg/"${CATEGORY}/${PF}"
ebuild_section "Writing VDB entry to '${dbdir}'..."
install -d "${dbdir}" || die "couldn't make pkg db directory (\"${dbdir}\")"
+ install -d "${ROOT%/}"/var/db/pkg/.cache || die "couldn't make pkg db cache"
local v
for v in CATEGORY CBUILD CFLAGS CHOST CXXFLAGS DEPEND DESCRIPTION EAPI \
diff --git a/ebuild/depend.bash b/ebuild/builtin_metadata.bash
index 40e9635..35f4085 100644
--- a/ebuild/depend.bash
+++ b/ebuild/builtin_metadata.bash
@@ -21,7 +21,7 @@
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
-ebuild_f_depend()
+ebuild_f_metadata()
{
local key
diff --git a/ebuild/ebuild.bash b/ebuild/ebuild.bash
index dcf61df..1cb57d1 100755
--- a/ebuild/ebuild.bash
+++ b/ebuild/ebuild.bash
@@ -138,6 +138,27 @@ ebuild_load_ebuild()
KEYWORDS="${KEYWORDS} ${E_KEYWORDS}"
}
+perform_hook()
+{
+ export HOOK=${1}
+ ebuild_notice "debug" "Starting hook '${HOOK}'"
+
+ local hook_dir
+ for hook_dir in ${PALUDIS_HOOK_DIRS} ; do
+ [[ -d "${hook_dir}/${HOOK}" ]] || continue
+ local hook_file
+ for hook_file in "${hook_dir}/${HOOK}/"*.bash ; do
+ [[ -e "${hook_file}" ]] || continue
+ ebuild_notice "debug" "Starting hook script '${hook_file}' for '${HOOK}'"
+ if ! bash "${hook_file}" ; then
+ ebuild_notice "warning" "Hook '${hook_file}' returned failure"
+ else
+ ebuild_notice "warning" "Hook '${hook_file}' returned success"
+ fi
+ done
+ done
+}
+
ebuild_main()
{
local action ebuild="$1"
@@ -145,11 +166,7 @@ ebuild_main()
for action in $@ ; do
case ${action} in
- metadata)
- ebuild_load_module depend
- ;;
-
- init|fetch|merge|unmerge|tidyup|updateenv|strip)
+ metadata|init|fetch|merge|unmerge|tidyup|strip)
ebuild_load_module builtin_${action}
;;
@@ -174,15 +191,19 @@ ebuild_main()
eval "export ebuild_real_${f}=\"$(which $f )\""
eval "${f}() { ebuild_notice qa 'global scope ${f}' ; $(which $f ) \"\$@\" ; }"
done
+ perform_hook ebuild_${action}_pre
PATH="" ebuild_load_ebuild "${ebuild}"
- ebuild_f_depend || die "${1} failed"
+ ebuild_f_metadata || die "${1} failed"
+ perform_hook ebuild_${action}_post
else
ebuild_load_ebuild "${ebuild}"
for action in $@ ; do
+ perform_hook ebuild_${action}_pre
ebuild_f_${action} || die "${action} failed"
if [[ ${action} == "init" ]] ; then
ebuild_load_ebuild "${ebuild}"
fi
+ perform_hook ebuild_${action}_post
done
fi
}
diff --git a/ebuild/echo_functions.bash b/ebuild/echo_functions.bash
index 522b397..f57d39b 100644
--- a/ebuild/echo_functions.bash
+++ b/ebuild/echo_functions.bash
@@ -75,7 +75,7 @@ ebuild_notice()
if [[ "${level_num}" -ge "${min_level_num}" ]] ; then
local upper_level=$(echo ${level} | ${ebuild_real_tr:-tr} '[:lower:]' '[:upper:]' )
- echo -n "${EBUILD_PROGRAM_NAME:-ebuild.bash}@$(date +%s ): "
+ echo -n "${EBUILD_PROGRAM_NAME:-ebuild.bash}@$(date +%s ): " 1>&2
echo "[${upper_level}.EBUILD] $* (from ${EBUILD:-?})" 1>&2
fi
true
diff --git a/hooks/Makefile.am b/hooks/Makefile.am
new file mode 100644
index 0000000..b067f71
--- /dev/null
+++ b/hooks/Makefile.am
@@ -0,0 +1,51 @@
+MAINTAINERCLEANFILES = Makefile.in
+CLEANFILES = *~
+SUBDIRS = .
+
+installhookcommonprogdir = $(libexecdir)/paludis/hooks/common
+installhookinstallallpostdir = $(libexecdir)/paludis/hooks/install_all_post
+
+installhookcommonprog_SCRIPTS = \
+ gnu_info_index.bash \
+ eselect_env_update.bash
+
+installhookinstallallpost_SCRIPTS = \
+ find_config_updates.bash
+
+TESTS_ENVIRONMENT = env \
+ PALUDIS_EBUILD_DIR="$(srcdir)/ebuild/" \
+ TEST_SCRIPT_DIR="$(srcdir)/" \
+ $(SHELL) $(top_srcdir)/ebuild/run_test.bash
+
+TESTS =
+EXTRA_DIST = \
+ $(installhookcommonprog_SCRIPTS) \
+ $(installhookinstallallpost_SCRIPTS) \
+ $(TESTS)
+
+check_SCRIPTS = $(TESTS)
+check_PROGRAMS =
+
+install-data-local :
+ install -d $(DESTDIR)/$(libexecdir)/paludis/hooks/uninstall_all_post
+ ln -sf ../common/gnu_info_index.bash $(DESTDIR)/$(libexecdir)/paludis/hooks/uninstall_all_post/
+ ln -sf ../common/eselect_env_update.bash $(DESTDIR)/$(libexecdir)/paludis/hooks/uninstall_all_post/
+ install -d $(DESTDIR)/$(libexecdir)/paludis/hooks/install_all_post
+ ln -sf ../common/gnu_info_index.bash $(DESTDIR)/$(libexecdir)/paludis/hooks/install_all_post/
+ install -d $(DESTDIR)/$(libexecdir)/paludis/hooks/install_post
+ ln -sf ../common/eselect_env_update.bash $(DESTDIR)/$(libexecdir)/paludis/hooks/install_post/
+ for d in install install_all fetch fetch_all uninstall uninstall_all \
+ sync sync_all ; do \
+ install -d $(DESTDIR)/$(datadir)/paludis/hooks/$${d}_pre ; \
+ touch $(DESTDIR)/$(datadir)/paludis/hooks/$${d}_pre/.keep ; \
+ install -d $(DESTDIR)/$(datadir)/paludis/hooks/$${d}_post ; \
+ touch $(DESTDIR)/$(datadir)/paludis/hooks/$${d}_post/.keep ; \
+ done
+ for d in metadata init fetch merge unmerge tidyup strip unpack compile \
+ install test setup config nofetch preinst postinst prerm posrtm ; do \
+ install -d $(DESTDIR)/$(datadir)/paludis/hooks/ebuild_$${d}_pre ; \
+ touch $(DESTDIR)/$(datadir)/paludis/hooks/ebuild_$${d}_pre/.keep ; \
+ install -d $(DESTDIR)/$(datadir)/paludis/hooks/ebuild_$${d}_post ; \
+ touch $(DESTDIR)/$(datadir)/paludis/hooks/ebuild_$${d}_post/.keep ; \
+ done
+
diff --git a/ebuild/builtin_updateenv.bash b/hooks/eselect_env_update.bash
index 4005baa..117c818 100644..100755
--- a/ebuild/builtin_updateenv.bash
+++ b/hooks/eselect_env_update.bash
@@ -1,5 +1,5 @@
#!/bin/bash
-# vim: set sw=4 sts=4 et :
+# vim: set et sw=4 sts=4 :
# Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
#
@@ -17,23 +17,11 @@
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
-builtin_updateenv()
-{
- cd "${PALUDIS_TMPDIR}"
- echo eselect env update
- eselect env update || die "eselect env update failed"
-}
+source /sbin/functions.sh
-ebuild_f_updateenv()
-{
- if hasq "updateenv" ${RESTRICT} ; then
- ebuild_section "Skipping builtin_updateenv (RESTRICT)"
- elif hasq "tidyup" ${SKIP_FUNCTIONS} ; then
- ebuild_section "Skipping builtin_updateenv (SKIP_FUNCTIONS)"
- else
- ebuild_section "Starting builtin_updateenv"
- builtin_updateenv
- ebuild_section "Done builtin_updateenv"
- fi
-}
+echo
+einfo "Regenerating environment..."
+eselect env update || exit 1
+einfo "Done regenerating environment"
+echo
diff --git a/hooks/find_config_updates.bash b/hooks/find_config_updates.bash
new file mode 100755
index 0000000..a570ff3
--- /dev/null
+++ b/hooks/find_config_updates.bash
@@ -0,0 +1,42 @@
+#!/bin/bash
+# vim: set et sw=4 sts=4 :
+
+# Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+#
+# 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 as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# 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
+
+source /sbin/functions.sh
+
+echo
+einfo "Searching for configuration files requiring action..."
+
+dir_count=0
+for dir in /etc ${CONFIG_PROTECT} ; do
+ [[ -d "${ROOT%/}/${dir}" ]] || continue
+ if [[ -n $(find "${ROOT%/}/${dir}" -iname '._cfg????_*' ) ]] ; then
+ einfo "Found files in ${ROOT%/}/${dir}"
+ dir_count=$((dir_count + 1))
+ fi
+done
+
+if [[ 0 -eq "${dir_count}" ]] ; then
+ einfo "No configuration file updates required"
+ exit 0
+else
+ ewarn "Found files in ${dir_count} directories"
+ ewarn "Your action is required"
+ exit 0
+fi
+
diff --git a/hooks/gnu_info_index.bash b/hooks/gnu_info_index.bash
new file mode 100755
index 0000000..fa1f87a
--- /dev/null
+++ b/hooks/gnu_info_index.bash
@@ -0,0 +1,82 @@
+#!/bin/bash
+# vim: set et sw=4 sts=4 :
+
+# Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+#
+# 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 as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+# 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
+
+source /sbin/functions.sh
+
+echo
+einfo "Checking whether the GNU info directory needs updating..."
+
+regen_info_dirs=
+for info_path in ${INFOPATH/:/ } ; do
+ info_path="${ROOT%/}/${info_path}"
+ [[ -d "${info_path}" ]] || continue
+ info_time=$(stat -c '%Y' "${info_path}" )
+
+ if [[ -f "${ROOT}/var/db/pkg/.cache/info_time_cache" ]] ; then
+ info_time_cache=$(stat -c '%Y' "${ROOT}"/var/db/pkg/.cache/info_time_cache )
+ [[ "${info_time}" -le "${info_time_cache}" ]] && continue
+ fi
+
+ regen_info_dirs="${regen_info_dirs} ${info_path}"
+done
+
+if [[ -z "${regen_info_dirs}" ]] ; then
+ einfo "No updates needed"
+ exit 0
+fi
+
+good_count=0
+bad_count=0
+
+for info_path in ${regen_info_dirs} ; do
+ einfo "Updating directory ${info_path}..."
+
+ [[ -e "${info_path}"/dir ]] && mv -f "${info_path}/"dir{,.old}
+
+ for d in ${regen_info_dirs}/* ; do
+ [[ -f "${d}" ]] || continue
+ [[ "${d}" != "${d%dir}" ]] && continue
+ [[ "${d}" != "${d%dir.old}" ]] && continue
+
+ is_bad=
+ /usr/bin/install-info --quiet --dir-file="${info_path}/dir" "${d}" 2>&1 | \
+ while read line ; do
+ [[ "${line/already exists, for file/}" != "${line}" ]] && continue
+ [[ "${line/warning: no info dir entry in /}" != "${line}" ]] && continue
+ is_bad=probably
+ done
+
+ if [[ -n "${is_bad}" ]] ; then
+ bad_count=$(( bad_count + 1 ))
+ else
+ good_count=$(( good_count + 1 ))
+ fi
+ done
+done
+
+touch "${ROOT}/var/db/pkg/.cache/info_time_cache"
+
+if [[ ${bad_count} -gt 0 ]] ; then
+ ewarn "Processed $(( good_count + bad_count )) info files, with ${bad_count} errors"
+ exit 1
+else
+ einfo "Processed ${good_count} info files"
+ exit 0
+fi
+
diff --git a/paludis/Makefile.am.m4 b/paludis/Makefile.am.m4
index ee0e6a3..8492060 100644
--- a/paludis/Makefile.am.m4
+++ b/paludis/Makefile.am.m4
@@ -37,6 +37,7 @@ AM_CXXFLAGS = -I$(top_srcdir)
DEFS= \
-DSYSCONFDIR=\"$(sysconfdir)\" \
-DLIBEXECDIR=\"$(libexecdir)\" \
+ -DDATADIR=\"$(datadir)\" \
-DBIGTEMPDIR=\"/var/tmp\"
EXTRA_DIST = about.hh.in Makefile.am.m4 paludis.hh.m4 files.m4 \
hashed_containers.hh.in testscriptlist
diff --git a/paludis/default_config.cc b/paludis/default_config.cc
index 9f40b01..fc1ee01 100644
--- a/paludis/default_config.cc
+++ b/paludis/default_config.cc
@@ -90,6 +90,9 @@ DefaultConfig::DefaultConfig() :
}
}
+ _root = root_prefix;
+ _config_dir = stringify(config_dir);
+
std::map<std::string, std::string> conf_vars;
conf_vars.insert(std::make_pair("ROOT", root_prefix));
diff --git a/paludis/default_config.hh b/paludis/default_config.hh
index dd30a8e..5bcd408 100644
--- a/paludis/default_config.hh
+++ b/paludis/default_config.hh
@@ -147,7 +147,8 @@ namespace paludis
static std::string _config_suffix;
static bool _config_suffix_can_be_set;
std::string _paludis_command;
-
+ std::string _root;
+ std::string _config_dir;
std::string _bashrc_files;
DefaultConfig();
@@ -476,6 +477,22 @@ namespace paludis
{
_paludis_command = s;
}
+
+ /**
+ * The ROOT.
+ */
+ std::string root() const
+ {
+ return _root;
+ }
+
+ /**
+ * The config directory.
+ */
+ std::string config_dir() const
+ {
+ return _config_dir;
+ }
};
}
diff --git a/paludis/default_environment.cc b/paludis/default_environment.cc
index 36a266c..069f94f 100644
--- a/paludis/default_environment.cc
+++ b/paludis/default_environment.cc
@@ -23,8 +23,11 @@
#include <paludis/match_package.hh>
#include <paludis/package_database.hh>
#include <paludis/repository.hh>
+#include <paludis/util/is_file_with_extension.hh>
+#include <paludis/util/log.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/system.hh>
+#include <paludis/util/dir_iterator.hh>
#include <vector>
using namespace paludis;
@@ -321,3 +324,103 @@ DefaultEnvironment::query_enabled_use_matching(const std::string & prefix,
return result;
}
+namespace
+{
+ void add_one_hook(const std::string & base, std::list<FSEntry> & result)
+ {
+ try
+ {
+ FSEntry r(base);
+ if (r.is_directory())
+ {
+ Log::get_instance()->message(ll_debug, "Adding hook directory '"
+ + base + "'");
+ result.push_back(r);
+ }
+ else
+ Log::get_instance()->message(ll_debug, "Skipping hook directory candidate '"
+ + base + "'");
+ }
+ catch (const FSError & e)
+ {
+ Log::get_instance()->message(ll_warning, "Caught exception '" +
+ e.message() + "' (" + e.what() + ") when checking hook "
+ "directory '" + base + "'");
+ }
+ }
+
+ const std::list<FSEntry> & get_hook_dirs()
+ {
+ static std::list<FSEntry> result;
+ static bool done_hooks(false);
+ if (! done_hooks)
+ {
+ add_one_hook(DefaultConfig::get_instance()->config_dir() + "/hooks", result);
+ add_one_hook(LIBEXECDIR "/paludis/hooks", result);
+ add_one_hook(DATADIR "/paludis/hooks", result);
+ done_hooks = true;
+ }
+ return result;
+ }
+
+ struct Hooker
+ {
+ std::string hook, paludis_command;
+
+ Hooker(const std::string & h, const std::string & p) :
+ hook(h),
+ paludis_command(p)
+ {
+ }
+
+ void operator() (const FSEntry & f) const
+ {
+ Context context("When running hook script '" + stringify(f) +
+ "' for hook '" + hook + "':");
+ Log::get_instance()->message(ll_debug, "Starting hook script '" +
+ stringify(f) + "' for '" + hook + "'");
+
+ int exit_status(run_command(make_env_command("bash '" + stringify(f) + "'")
+ ("ROOT", DefaultConfig::get_instance()->root())
+ ("HOOK", hook)
+ ("PALUDIS_COMMAND", paludis_command)));
+ if (0 == exit_status)
+ Log::get_instance()->message(ll_debug, "Hook '" + stringify(f)
+ + "' returned success '" + stringify(exit_status) + "'");
+ else
+ Log::get_instance()->message(ll_warning, "Hook '" + stringify(f)
+ + "' returned failure '" + stringify(exit_status) + "'");
+ }
+ };
+}
+
+void
+DefaultEnvironment::perform_hook(const std::string & hook) const
+{
+ Context context("When triggering hook '" + hook + "'");
+ Log::get_instance()->message(ll_debug, "Starting hook '" + hook + "'");
+
+ const std::list<FSEntry> & hook_dirs(get_hook_dirs());
+
+ for (std::list<FSEntry>::const_iterator h(hook_dirs.begin()),
+ h_end(hook_dirs.end()) ; h != h_end ; ++h)
+ {
+ FSEntry hh(*h / hook);
+ if (! hh.is_directory())
+ continue;
+
+ std::list<FSEntry> hooks;
+ std::copy(DirIterator(hh), DirIterator(),
+ filter_inserter(std::back_inserter(hooks), IsFileWithExtension(".bash")));
+ std::for_each(hooks.begin(), hooks.end(), Hooker(hook, paludis_command()));
+ }
+}
+
+std::string
+DefaultEnvironment::hook_dirs() const
+{
+ const std::list<FSEntry> & hook_dirs(get_hook_dirs());
+ return join(hook_dirs.begin(), hook_dirs.end(), " ");
+}
+
+
diff --git a/paludis/default_environment.hh b/paludis/default_environment.hh
index b4a7ecc..1c4a709 100644
--- a/paludis/default_environment.hh
+++ b/paludis/default_environment.hh
@@ -61,10 +61,14 @@ namespace paludis
virtual std::string bashrc_files() const;
+ virtual std::string hook_dirs() const;
+
virtual std::string paludis_command() const;
virtual UseFlagNameCollection::Pointer query_enabled_use_matching(
const std::string & prefix, const PackageDatabaseEntry *) const;
+
+ virtual void perform_hook(const std::string & hook) const;
};
}
#endif
diff --git a/paludis/ebuild.cc b/paludis/ebuild.cc
index fa22db1..fa306fc 100644
--- a/paludis/ebuild.cc
+++ b/paludis/ebuild.cc
@@ -80,6 +80,7 @@ EbuildCommand::operator() ()
("PALUDIS_TMPDIR", BIGTEMPDIR "/paludis/")
("PALUDIS_CONFIG_DIR", SYSCONFDIR "/paludis/")
("PALUDIS_BASHRC_FILES", params.get<ecpk_environment>()->bashrc_files())
+ ("PALUDIS_HOOK_DIRS", params.get<ecpk_environment>()->hook_dirs())
("PALUDIS_COMMAND", params.get<ecpk_environment>()->paludis_command())
("KV", kernel_version())
("PALUDIS_EBUILD_LOG_LEVEL", Log::get_instance()->log_level_string())
@@ -202,7 +203,7 @@ EbuildInstallCommand::commands() const
return "merge";
else
return "init setup unpack compile test install strip preinst "
- "merge postinst updateenv tidyup";
+ "merge postinst tidyup";
}
bool
diff --git a/paludis/environment.hh b/paludis/environment.hh
index 3b5b483..b8d8d50 100644
--- a/paludis/environment.hh
+++ b/paludis/environment.hh
@@ -110,6 +110,11 @@ namespace paludis
virtual std::string bashrc_files() const = 0;
/**
+ * Our hook directories.
+ */
+ virtual std::string hook_dirs() const = 0;
+
+ /**
* How to run paludis.
*/
virtual std::string paludis_command() const = 0;
@@ -149,6 +154,11 @@ namespace paludis
* Remove packages from world, if they are there.
*/
void remove_appropriate_from_world(DepAtom::ConstPointer) const;
+
+ /**
+ * Perform a hook.
+ */
+ virtual void perform_hook(const std::string & Hook) const = 0;
};
}
diff --git a/paludis/test_environment.hh b/paludis/test_environment.hh
index 5fe759a..ed55e79 100644
--- a/paludis/test_environment.hh
+++ b/paludis/test_environment.hh
@@ -61,6 +61,11 @@ namespace paludis
return "";
}
+ virtual std::string hook_dirs() const
+ {
+ return "";
+ }
+
virtual std::string paludis_command() const
{
return "false";
@@ -71,6 +76,10 @@ namespace paludis
{
return UseFlagNameCollection::Pointer(new UseFlagNameCollection);
}
+
+ virtual void perform_hook(const std::string &) const
+ {
+ }
};
}
diff --git a/src/install.cc b/src/install.cc
index 3949de5..bcda7c9 100644
--- a/src/install.cc
+++ b/src/install.cc
@@ -336,6 +336,11 @@ do_install()
if (CommandLine::get_instance()->a_fetch.specified())
opts.set<p::io_fetchonly>(true);
+ if (opts.get<p::io_fetchonly>())
+ env->perform_hook("fetch_all_pre");
+ else
+ env->perform_hook("install_all_pre");
+
for (p::DepList::Iterator dep(dep_list.begin()), dep_end(dep_list.end()) ;
dep != dep_end ; ++dep)
{
@@ -361,9 +366,19 @@ do_install()
p::stringify(max_count) + ") Installing " + cpv);
}
+ if (opts.get<p::io_fetchonly>())
+ env->perform_hook("fetch_pre");
+ else
+ env->perform_hook("install_pre");
+
env->package_database()->fetch_repository(dep->get<p::dle_repository>())->
install(dep->get<p::dle_name>(), dep->get<p::dle_version>(), opts);
+ if (opts.get<p::io_fetchonly>())
+ env->perform_hook("fetch_post");
+ else
+ env->perform_hook("install_post");
+
if (! opts.get<p::io_fetchonly>())
{
// figure out if we need to unmerge anything
@@ -402,6 +417,7 @@ do_install()
cout << "* " << colour(cl_package_name, *c) << endl;
cout << endl;
+ env->perform_hook("uninstall_all_pre");
for (p::PackageDatabaseEntryCollection::Iterator c(clean_list.begin()),
c_end(clean_list.end()) ; c != c_end ; ++c)
{
@@ -411,12 +427,21 @@ do_install()
cerr << xterm_title("(" + p::stringify(current_count) + " of " +
p::stringify(max_count) + ") Cleaning " + cpv + ": " + stringify(*c));
+ env->perform_hook("uninstall_pre");
env->package_database()->fetch_repository(c->get<p::pde_repository>())->
uninstall(c->get<p::pde_name>(), c->get<p::pde_version>(), opts);
+ env->perform_hook("uninstall_post");
}
+ env->perform_hook("uninstall_all_post");
}
}
}
+
+ if (opts.get<p::io_fetchonly>())
+ env->perform_hook("fetch_all_post");
+ else
+ env->perform_hook("install_all_post");
+
cout << endl;
}
catch (const p::PackageInstallActionError & e)
@@ -495,7 +520,6 @@ do_install()
return 1;
}
-
catch (const p::DepListStackTooDeepError & e)
{
cout << endl;
diff --git a/src/sync.cc b/src/sync.cc
index b5a8485..d174973 100644
--- a/src/sync.cc
+++ b/src/sync.cc
@@ -78,12 +78,15 @@ int do_sync()
p::create_inserter<p::RepositoryName>(std::inserter(
repo_names, repo_names.begin())));
+ env->perform_hook("sync_all_pre");
for (std::set<p::RepositoryName>::iterator r(repo_names.begin()), r_end(repo_names.end()) ;
r != r_end ; ++r)
{
try
{
+ env->perform_hook("sync_pre");
return_code |= do_one_sync(env->package_database()->fetch_repository(*r));
+ env->perform_hook("sync_post");
}
catch (const p::NoSuchRepositoryError & e)
{
@@ -92,6 +95,7 @@ int do_sync()
std::cout << "Sync " << *r << " failed" << std::endl;
}
}
+ env->perform_hook("sync_all_post");
}
return return_code;
diff --git a/src/uninstall.cc b/src/uninstall.cc
index 47c40bf..fe3419e 100644
--- a/src/uninstall.cc
+++ b/src/uninstall.cc
@@ -111,6 +111,7 @@ do_uninstall()
if (CommandLine::get_instance()->a_no_config_protection.specified())
opts.set<p::io_noconfigprotect>(true);
+ env->perform_hook("uninstall_all_pre");
for (p::PackageDatabaseEntryCollection::Iterator pkg(unmerge->begin()), pkg_end(unmerge->end()) ;
pkg != pkg_end ; ++pkg)
{
@@ -124,9 +125,12 @@ do_uninstall()
cerr << xterm_title("(" + p::stringify(++current_count) + " of " +
p::stringify(max_count) + ") Uninstalling " + cpv);
+ env->perform_hook("uninstall_pre");
env->package_database()->fetch_repository(pkg->get<p::pde_repository>())->
uninstall(pkg->get<p::pde_name>(), pkg->get<p::pde_version>(), opts);
+ env->perform_hook("uninstall_post");
}
+ env->perform_hook("uninstall_all_post");
return return_code;
}