Exheredludis/paludis/repositories/e/ebuild.cc
Benedikt Morbach 3169132a32 set USER and LOGNAME when running with userpriv
some builds/tests get confused when running as paludisbuild with USER=root.
2018-04-09 20:49:00 +02:00

1438 lines
57 KiB
C++

/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
* Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2013 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/repositories/e/ebuild.hh>
#include <paludis/repositories/e/ebuild_id.hh>
#include <paludis/repositories/e/e_repository.hh>
#include <paludis/repositories/e/eapi.hh>
#include <paludis/repositories/e/dep_parser.hh>
#include <paludis/repositories/e/pipe_command_handler.hh>
#include <paludis/util/system.hh>
#include <paludis/util/process.hh>
#include <paludis/util/strip.hh>
#include <paludis/util/log.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/options.hh>
#include <paludis/util/map.hh>
#include <paludis/util/join.hh>
#include <paludis/util/tokeniser.hh>
#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/util/wrapped_output_iterator.hh>
#include <paludis/util/iterator_funcs.hh>
#include <paludis/util/destringify.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/set.hh>
#include <paludis/util/env_var_names.hh>
#include <paludis/about.hh>
#include <paludis/environment.hh>
#include <paludis/util/config_file.hh>
#include <paludis/package_id.hh>
#include <paludis/metadata_key.hh>
#include <paludis/action.hh>
#include <paludis/elike_choices.hh>
#include <paludis/output_manager.hh>
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>
#include <time.h>
#include <functional>
#include <list>
#include <set>
#include "config.h"
/** \file
* Imp for ebuild.hh things.
*
* \ingroup grpebuildinterface
*/
using namespace paludis;
using namespace paludis::erepository;
EbuildCommand::EbuildCommand(const EbuildCommandParams & p) :
params(p)
{
}
EbuildCommand::~EbuildCommand() = default;
bool
EbuildCommand::success()
{
return true;
}
bool
EbuildCommand::failure()
{
return false;
}
namespace
{
std::string get_jobs(const std::shared_ptr<const PackageID> & id)
{
std::shared_ptr<const ChoiceValue> choice;
if (id->choices_key())
choice = id->choices_key()->parse_value()->find_by_name_with_prefix(ELikeJobsChoiceValue::canonical_name_with_prefix());
if (choice && choice->enabled())
return choice->parameter();
else
return "";
}
bool get_trace(const std::shared_ptr<const PackageID> & id)
{
std::shared_ptr<const ChoiceValue> choice;
if (id->choices_key())
choice = id->choices_key()->parse_value()->find_by_name_with_prefix(ELikeTraceChoiceValue::canonical_name_with_prefix());
return choice && choice->enabled();
}
}
bool
EbuildCommand::operator() ()
{
Context context("When running an ebuild command on '" + stringify(*params.package_id()) + "':");
const auto & package_id = params.package_id();
const auto & eapi = package_id->eapi()->supported();
Process process(ProcessCommand(getenv_with_default(env_vars::ebuild_dir, LIBEXECDIR "/paludis") + "/ebuild.bash '"
+ ebuild_file() + "' " + commands()));
if (! eapi)
throw InternalError(PALUDIS_HERE, "Tried to run EbuildCommand on an unsupported EAPI");
if (params.clearenv())
process.clearenv();
if (params.sydbox())
process.sydbox();
else if (params.sandbox())
process.sandbox();
if (params.userpriv())
{
if (eapi->userpriv_cannot_use_root())
{
if (0 == params.environment()->reduced_uid() || 0 == params.environment()->reduced_gid())
if (getenv_with_default(env_vars::bypass_userpriv_checks, "").empty())
throw ActionFailedError("Need to be able to use non-0 user and group for userpriv for '" +
stringify(*package_id) + "'");
}
process
.setuid_setgid(params.environment()->reduced_uid(), params.environment()->reduced_gid())
.setenv("USER", params.environment()->reduced_username())
.setenv("LOGNAME", params.environment()->reduced_username());
}
using namespace std::placeholders;
process.pipe_command_handler("PALUDIS_PIPE_COMMAND",
std::bind(&pipe_command_handler,
params.environment(),
package_id,
params.permitted_directories(),
params.parts(),
params.volatile_files(),
in_metadata_generation(), _1,
params.maybe_output_manager()));
std::shared_ptr<const FSPathSequence> syncers_dirs(params.environment()->syncers_dirs());
std::shared_ptr<const FSPathSequence> bashrc_files(params.environment()->bashrc_files());
std::shared_ptr<const FSPathSequence> fetchers_dirs(params.environment()->fetchers_dirs());
std::shared_ptr<const FSPathSequence> hook_dirs(params.environment()->hook_dirs());
const auto & options = eapi->ebuild_options();
const auto & tools = eapi->tools_options();
const auto & environment_variables = eapi->ebuild_environment_variables();
process
.setenv("PV", stringify(package_id->version().remove_revision()))
.setenv("PR", stringify(package_id->version().revision_only()))
.setenv("PN", stringify(package_id->name().package()))
.setenv("PVR", stringify(package_id->version()))
.setenv("CATEGORY", stringify(package_id->name().category()))
.setenv("REPOSITORY", stringify(package_id->repository_name()))
.setenv("EAPI", stringify(package_id->eapi()->exported_name()))
.setenv("PKGMANAGER", PALUDIS_PACKAGE "-" + stringify(PALUDIS_VERSION_MAJOR) + "." +
stringify(PALUDIS_VERSION_MINOR) + "." +
stringify(PALUDIS_VERSION_MICRO) + stringify(PALUDIS_VERSION_SUFFIX) +
(std::string(PALUDIS_GIT_HEAD).empty() ?
std::string("") : "-git-" + std::string(PALUDIS_GIT_HEAD)))
.setenv("PALUDIS_TMPDIR", stringify(params.builddir()))
.setenv("PALUDIS_PACKAGE_BUILDDIR", stringify(params.package_builddir()))
.setenv("PALUDIS_CONFIG_DIR", SYSCONFDIR "/paludis/")
.setenv("PALUDIS_BASHRC_FILES", join(bashrc_files->begin(), bashrc_files->end(), " "))
.setenv("PALUDIS_HOOK_DIRS", join(hook_dirs->begin(), hook_dirs->end(), " "))
.setenv("PALUDIS_FETCHERS_DIRS", join(fetchers_dirs->begin(), fetchers_dirs->end(), " "))
.setenv("PALUDIS_SYNCERS_DIRS", join(syncers_dirs->begin(), syncers_dirs->end(), " "))
.setenv("PALUDIS_REDUCED_GID", stringify(params.environment()->reduced_gid()))
.setenv("PALUDIS_REDUCED_UID", stringify(params.environment()->reduced_uid()))
.setenv("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
.setenv("PALUDIS_EBUILD_QUIET", "")
.setenv("PALUDIS_EBUILD_DIR", getenv_with_default(env_vars::ebuild_dir, LIBEXECDIR "/paludis"))
.setenv("PALUDIS_UTILITY_PATH_SUFFIXES", options->utility_path_suffixes())
.setenv("PALUDIS_EBUILD_MODULE_SUFFIXES", options->ebuild_module_suffixes())
.setenv("PALUDIS_NON_EMPTY_VARIABLES", options->non_empty_variables())
.setenv("PALUDIS_DIRECTORY_VARIABLES", options->directory_variables())
.setenv("PALUDIS_EBUILD_MUST_NOT_SET_VARIABLES",
options->ebuild_must_not_set_variables())
.setenv("PALUDIS_ECLASS_MUST_NOT_SET_VARIABLES",
options->eclass_must_not_set_variables())
.setenv("PALUDIS_SAVE_VARIABLES", options->save_variables())
.setenv("PALUDIS_SAVE_BASE_VARIABLES", options->save_base_variables())
.setenv("PALUDIS_SAVE_UNMODIFIABLE_VARIABLES",
options->save_unmodifiable_variables())
.setenv("PALUDIS_DIRECTORY_IF_EXISTS_VARIABLES",
options->directory_if_exists_variables())
.setenv("PALUDIS_SOURCE_MERGED_VARIABLES",
options->source_merged_variables())
.setenv("PALUDIS_BRACKET_MERGED_VARIABLES",
options->bracket_merged_variables())
.setenv("PALUDIS_BRACKET_MERGED_VARIABLES_ANNOTATABLE",
options->bracket_merged_variables_annotatable())
.setenv("PALUDIS_BRACKET_MERGED_VARIABLES_ANNOTATION",
options->bracket_merged_variables_annotation())
.setenv("PALUDIS_MUST_NOT_CHANGE_VARIABLES",
options->must_not_change_variables())
.setenv("PALUDIS_MUST_NOT_SET_VARS_STARTING_WITH",
options->must_not_set_vars_starting_with())
.setenv("PALUDIS_MUST_NOT_CHANGE_AFTER_SOURCE_VARIABLES",
options->must_not_change_after_source_variables())
.setenv("PALUDIS_RDEPEND_DEFAULTS_TO_DEPEND",
options->rdepend_defaults_to_depend() ? "yes" : "")
.setenv("PALUDIS_F_FUNCTION_PREFIX", options->f_function_prefix())
.setenv("PALUDIS_IGNORE_PIVOT_ENV_FUNCTIONS",
options->ignore_pivot_env_functions())
.setenv("PALUDIS_IGNORE_PIVOT_ENV_VARIABLES",
options->ignore_pivot_env_variables())
.setenv("PALUDIS_LOAD_MODULES", options->load_modules())
.setenv("PALUDIS_EBUILD_FUNCTIONS", options->ebuild_functions())
.setenv("PALUDIS_NO_S_WORKDIR_FALLBACK",
options->no_s_workdir_fallback() ? "yes" : "")
.setenv("PALUDIS_BINARY_DISTDIR_VARIABLE", environment_variables->env_distdir())
.setenv("PALUDIS_ECONF_EXTRA_OPTIONS", tools->econf_extra_options())
.setenv("PALUDIS_ECONF_EXTRA_OPTIONS_HELP_DEPENDENT",
tools->econf_extra_options_help_dependent())
.setenv("PALUDIS_UNPACK_UNRECOGNISED_IS_FATAL",
tools->unpack_unrecognised_is_fatal() ? "yes" : "")
.setenv("PALUDIS_UNPACK_FIX_PERMISSIONS",
tools->unpack_fix_permissions() ? "yes" : "")
.setenv("PALUDIS_UNPACK_ANY_PATH",
tools->unpack_any_path() ? "yes" : "")
.setenv("PALUDIS_UNPACK_CASE_INSENSITIVE",
tools->unpack_case_insensitive() ? "yes" : "")
.setenv("PALUDIS_UNPACK_SUFFIXES", tools->unpack_suffixes())
.setenv("PALUDIS_BEST_HAS_VERSION_HOST_ROOT",
tools->best_has_version_host_root() ? "yes" : "")
.setenv("PALUDIS_DODOC_R", tools->dodoc_r() ? "yes" : "")
.setenv("PALUDIS_DOINS_SYMLINK", tools->doins_symlink() ? "yes" : "")
.setenv("PALUDIS_DOMAN_LANG_FILENAMES",
tools->doman_lang_filenames() ? "yes" : "")
.setenv("PALUDIS_DOMAN_LANG_FILENAMES_OVERRIDES",
tools->doman_lang_filenames_overrides() ? "yes" : "")
.setenv("PALUDIS_DOSYM_NO_MKDIR", tools->dosym_mkdir() ? "" : "yes")
.setenv("PALUDIS_NEW_STDIN", tools->new_stdin() ? "yes" : "")
.setenv("PALUDIS_USE_WITH_ENABLE_EMPTY_THIRD_ARGUMENT",
tools->use_with_enable_empty_third_argument() ? "yes" : "")
.setenv("PALUDIS_FAILURE_IS_FATAL", tools->failure_is_fatal() ? "yes" : "")
.setenv("PALUDIS_DIE_SUPPORTS_DASH_N",
tools->die_supports_dash_n() ? "yes" : "")
.setenv("PALUDIS_UNPACK_FROM_VAR", environment_variables->env_distdir())
.setenv("PALUDIS_IMAGE_DIR_VAR", environment_variables->env_d())
.setenv("PALUDIS_TEMP_DIR_VAR", environment_variables->env_t())
.setenv("PALUDIS_NAME_VERSION_REVISION_VAR", environment_variables->env_pf())
.setenv("PALUDIS_EBUILD_PHASE_VAR", environment_variables->env_ebuild_phase())
.setenv("PALUDIS_EBUILD_PHASE_FUNC_VAR", environment_variables->env_ebuild_phase_func())
.setenv("PALUDIS_PIPE_COMMANDS_SUPPORTED", "yes")
.setenv("PALUDIS_PIPE_COMMANDS_STATUS_SUPPORTED", "yes")
.setenv("PALUDIS_PIPE_COMMAND_DELIM", "\2")
.setenv("PALUDIS_BASH_COMPAT", options->bash_compat())
.setenv("PALUDIS_SHELL_OPTIONS", options->shell_options())
.setenv("PALUDIS_SHELL_OPTIONS_GLOBAL", options->shell_options_global())
.setenv("SLOT", "")
.setenv("PALUDIS_PROFILE_DIR", "")
.setenv("PALUDIS_PROFILE_DIRS", "")
.setenv("PALUDIS_PROFILES_DIRS", "")
.setenv("ROOT", params.root());
if (! params.package_id()->eapi()->supported()->ebuild_environment_variables()->env_merge_type().empty())
process.setenv(params.package_id()->eapi()->supported()->ebuild_environment_variables()->env_merge_type(), "");
extend_command(process);
if (! environment_variables->env_kv().empty())
process.setenv(environment_variables->env_kv(), kernel_version());
if (! environment_variables->env_portdir().empty())
process.setenv(environment_variables->env_portdir(), stringify(params.portdir()));
if (! environment_variables->env_distdir().empty())
process.setenv(environment_variables->env_distdir(), stringify(params.distdir()));
if (! environment_variables->env_p().empty())
process.setenv(environment_variables->env_p(),
stringify(package_id->name().package()) + "-" +
stringify(package_id->version().remove_revision()));
if (! environment_variables->env_pf().empty())
process.setenv(environment_variables->env_pf(),
stringify(package_id->name().package()) + "-" +
stringify(package_id->version()));
if (! environment_variables->env_filesdir().empty())
process.setenv(environment_variables->env_filesdir(), stringify(params.files_dir()));
if (! eapi->ebuild_metadata_variables()->iuse_effective()->name().empty())
if (package_id->raw_iuse_effective_key())
{
auto iu(package_id->raw_iuse_effective_key()->parse_value());
process.setenv(eapi->ebuild_metadata_variables()->iuse_effective()->name(), join(iu->begin(), iu->end(), " "));
}
if (options->support_eclasses())
process
.setenv("ECLASSDIR", stringify(*params.eclassdirs()->begin()))
.setenv("ECLASSDIRS", join(params.eclassdirs()->begin(), params.eclassdirs()->end(), " "));
if (options->support_exlibs())
process
.setenv("EXLIBSDIRS", join(params.exlibsdirs()->begin(), params.exlibsdirs()->end(), " "));
if (! environment_variables->env_jobs().empty())
process
.setenv("PALUDIS_JOBS_VAR", environment_variables->env_jobs())
.setenv(environment_variables->env_jobs(), get_jobs(package_id));
process.setenv("PALUDIS_PREFIX_IMAGE_VAR", environment_variables->env_ed());
if (! environment_variables->env_eprefix().empty())
process.setenv(environment_variables->env_eprefix(), "");
if (! environment_variables->env_eroot().empty())
process.setenv(environment_variables->env_eroot(), params.root());
process.setenv("PALUDIS_TRACE", get_trace(package_id) ? "yes" : "");
if (options->want_portage_emulation_vars())
add_portage_vars(process);
if (params.maybe_output_manager())
process
.capture_stderr(params.maybe_output_manager()->stderr_stream())
.capture_stdout(params.maybe_output_manager()->stdout_stream())
.use_ptys();
if (do_run_command(process))
return success();
else
return failure();
}
std::string
EbuildCommand::ebuild_file() const
{
return stringify(params.ebuild_file());
}
void
EbuildCommand::add_portage_vars(Process & process) const
{
process
.setenv("PORTAGE_ACTUAL_DISTDIR", stringify(params.distdir()))
.setenv("PORTAGE_BASHRC", "/dev/null")
.setenv("PORTAGE_BUILDDIR", stringify(params.package_builddir()))
.setenv("PORTAGE_GID", "0")
.setenv("PORTAGE_INST_GID", "0")
.setenv("PORTAGE_INST_UID", "0")
.setenv("PORTAGE_MASTER_PID", stringify(::getpid()))
.setenv("PORTAGE_NICENCESS", stringify(::getpriority(PRIO_PROCESS, 0)))
.setenv("PORTAGE_TMPDIR", stringify(params.builddir()))
.setenv("PORTAGE_TMPFS", "/dev/shm")
.setenv("PORTAGE_WORKDIR_MODE", "0700");
}
bool
EbuildCommand::in_metadata_generation() const
{
return false;
}
bool
EbuildCommand::do_run_command(Process & process)
{
return 0 == process.run().wait();
}
EbuildMetadataCommand::EbuildMetadataCommand(const EbuildCommandParams & p) :
EbuildCommand(p)
{
}
EbuildMetadataCommand::~EbuildMetadataCommand() = default;
std::string
EbuildMetadataCommand::commands() const
{
return params.commands();
}
bool
EbuildMetadataCommand::failure()
{
return EbuildCommand::failure();
}
void
EbuildMetadataCommand::extend_command(Process & process)
{
process
.setenv("PALUDIS_EBUILD_QUIET", "yes")
.setuid_setgid(params.environment()->reduced_uid(), params.environment()->reduced_gid())
;
}
bool
EbuildMetadataCommand::in_metadata_generation() const
{
return true;
}
bool
EbuildMetadataCommand::do_run_command(Process & process)
{
bool ok(false);
keys = std::make_shared<Map<std::string, std::string>>();
try
{
Context context("When running ebuild command to generate metadata for '" + stringify(*params.package_id()) + "':");
std::stringstream prog, prog_err, metadata;
process
.capture_stdout(prog)
.capture_stderr(prog_err)
.capture_output_to_fd(metadata, -1, "PALUDIS_METADATA_FD");
int exit_status(process.run().wait());
KeyValueConfigFile f(metadata, { kvcfo_disallow_continuations, kvcfo_disallow_comments , kvcfo_disallow_space_around_equals,
kvcfo_disallow_unquoted_values, kvcfo_disallow_source , kvcfo_disallow_variables, kvcfo_preserve_whitespace },
&KeyValueConfigFile::no_defaults, &KeyValueConfigFile::no_transformation);
std::copy(f.begin(), f.end(), keys->inserter());
if (0 == exit_status)
ok = true;
captured_stdout = prog.str();
captured_stderr = prog_err.str();
}
catch (const InternalError &)
{
throw;
}
catch (const Exception & e)
{
Log::get_instance()->message("e.ebuild.cache_failure", ll_warning, lc_context) << "Caught exception '"
<< e.message() << "' (" << e.what() << ") when generating cache for '"
<< *params.package_id() << "'";
}
if (ok)
return true;
else
{
Log::get_instance()->message("e.ebuild.cache_failure", ll_warning, lc_context) << "Could not generate cache for '"
<< *params.package_id() << "', stdout says '" << captured_stdout << "' and stderr says '" << captured_stderr << "'";
keys = std::make_shared<Map<std::string, std::string>>();
keys->insert("EAPI", EAPIData::get_instance()->unknown_eapi()->name());
return false;
}
}
namespace
{
std::string get(const std::shared_ptr<const Map<std::string, std::string> > & k, const std::string & s)
{
Map<std::string, std::string>::ConstIterator i(k->find(s));
if (k->end() == i)
return "";
return i->second;
}
}
void
EbuildMetadataCommand::load(const std::shared_ptr<const EbuildID> & id)
{
Context context("When loading generated metadata for '" + stringify(*params.package_id()) + "':");
if (! keys)
throw InternalError(PALUDIS_HERE, "keys is 0");
if (! id->eapi()->supported())
{
Log::get_instance()->message("e.ebuild.preload_eapi.unsupported", ll_debug, lc_context)
<< "ID pre-load EAPI '" << id->eapi()->name() << "' not supported";
if (! captured_stdout.empty())
id->load_captured_stdout("STDERR", "Captured stdout", mkt_normal, captured_stdout);
if (! captured_stderr.empty())
id->load_captured_stderr("STDERR", "Captured stderr", mkt_normal, captured_stderr);
return;
}
else
Log::get_instance()->message("e.ebuild.preload_eapi.supported", ll_debug, lc_context)
<< "ID pre-load EAPI '" << id->eapi()->name() << "' is supported";
std::string s(get(keys, id->eapi()->supported()->ebuild_metadata_variables()->eapi()->name()));
if (s.empty())
{
auto repo(params.environment()->fetch_repository(id->repository_name()));
auto e_repo(std::static_pointer_cast<const ERepository>(repo));
s = e_repo->params().eapi_when_unspecified();
}
if (id->eapi()->name() != s)
{
Log::get_instance()->message("e.ebuild.postload_eapi.mismatch", ll_warning, lc_context)
<< "Post-source EAPI '" << s << "' does not match pre-source EAPI '" << id->eapi()->name() << "', treating as unknown";
id->set_eapi(EAPIData::get_instance()->unknown_eapi()->name());
}
if (! id->eapi()->supported())
{
Log::get_instance()->message("e.ebuild.postload_eapi.unsupported", ll_debug, lc_context)
<< "ID post-load EAPI '" << id->eapi()->name() << "' not supported";
if (! captured_stdout.empty())
id->load_captured_stdout("STDERR", "Captured stdout", mkt_normal, captured_stdout);
if (! captured_stderr.empty())
id->load_captured_stderr("STDERR", "Captured stderr", mkt_normal, captured_stderr);
return;
}
else
Log::get_instance()->message("e.ebuild.postload_eapi.supported", ll_debug, lc_context)
<< "ID post-load EAPI '" << id->eapi()->name() << "' is supported";
if (! captured_stdout.empty())
id->load_captured_stdout("STDERR", "Captured stdout", mkt_internal, captured_stdout);
if (! captured_stderr.empty())
id->load_captured_stderr("STDERR", "Captured stderr", mkt_internal, captured_stderr);
const EAPIEbuildMetadataVariables & m(*id->eapi()->supported()->ebuild_metadata_variables());
if (! m.short_description()->name().empty())
id->load_short_description(m.short_description()->name(), m.short_description()->description(), get(keys, m.short_description()->name()));
if (! m.long_description()->name().empty())
{
std::string value(get(keys, m.long_description()->name()));
if (! value.empty())
id->load_long_description(m.long_description()->name(), m.long_description()->description(), value);
}
if (! m.dependencies()->name().empty())
id->load_dependencies(m.dependencies()->name(), m.dependencies()->description(), get(keys, m.dependencies()->name()));
else
{
if (! m.build_depend()->name().empty())
id->load_build_depend(m.build_depend()->name(), m.build_depend()->description(), get(keys, m.build_depend()->name()), false);
if (! m.run_depend()->name().empty())
{
if (id->eapi()->supported()->ebuild_options()->rdepend_defaults_to_depend())
{
if (! get(keys, "PALUDIS_EBUILD_RDEPEND_WAS_SET").empty())
id->load_run_depend(m.run_depend()->name(), m.run_depend()->description(),
get(keys, m.run_depend()->name()), false);
else
id->load_run_depend(m.run_depend()->name(), m.run_depend()->description(),
get(keys, "PALUDIS_EBUILD_DEPEND") + " " + get(keys, m.run_depend()->name()), false);
}
else
id->load_run_depend(m.run_depend()->name(), m.run_depend()->description(),
get(keys, m.run_depend()->name()), false);
}
if (! m.pdepend()->name().empty())
id->load_post_depend(m.pdepend()->name(), m.pdepend()->description(), get(keys, m.pdepend()->name()), false);
}
if (! m.slot()->name().empty())
{
try
{
Context c("When setting SLOT:");
std::string slot(get(keys, m.slot()->name()));
if (slot.empty())
{
Log::get_instance()->message("e.ebuild.no_slot", ll_qa, lc_context)
<< "Package '" << *id << "' set SLOT=\"\", using SLOT=\"0\" instead";
slot = "0";
}
id->load_slot(m.slot(), slot);
}
catch (const InternalError &)
{
throw;
}
catch (const Exception & e)
{
Log::get_instance()->message("e.ebuild.bad_slot", ll_warning, lc_context)
<< "Setting SLOT for '" << *id << "' failed due to exception '"
<< e.message() << "' (" << e.what() << ")";
id->load_slot(m.slot(), "0");
}
}
if (! m.src_uri()->name().empty())
id->load_src_uri(m.src_uri(), get(keys, m.src_uri()->name()));
if (! m.homepage()->name().empty())
id->load_homepage(m.homepage(), get(keys, m.homepage()->name()));
if (! m.license()->name().empty())
id->load_license(m.license(), get(keys, m.license()->name()));
if (! m.iuse()->name().empty())
id->load_iuse(m.iuse(), get(keys, m.iuse()->name()));
if (! m.myoptions()->name().empty())
id->load_myoptions(m.myoptions(), get(keys, m.myoptions()->name()));
if (! m.required_use()->name().empty())
id->load_required_use(m.required_use(), get(keys, m.required_use()->name()));
if (! m.inherited()->name().empty())
id->load_inherited(m.inherited(), get(keys, m.inherited()->name()));
if (! m.keywords()->name().empty())
id->load_keywords(m.keywords(), get(keys, m.keywords()->name()));
if (! m.restrictions()->name().empty())
id->load_restrict(m.restrictions(), get(keys, m.restrictions()->name()));
if (! m.properties()->name().empty())
id->load_properties(m.properties(), get(keys, m.properties()->name()));
if (! m.use()->name().empty())
id->load_use(m.use(), get(keys, m.use()->name()));
if (! m.generated_from()->name().empty())
id->load_generated_from(m.generated_from(), get(keys, m.generated_from()->name()));
if (! m.generated_time()->name().empty())
id->load_generated_time(m.generated_time()->name(), m.generated_time()->description(), get(keys, m.generated_time()->name()));
if (! m.generated_using()->name().empty())
id->load_generated_using(m.generated_using()->name(), m.generated_using()->description(), get(keys, m.generated_using()->name()));
if (! m.upstream_changelog()->name().empty())
{
std::string value(get(keys, m.upstream_changelog()->name()));
if (! value.empty())
id->load_upstream_changelog(m.upstream_changelog(), value);
}
if (! m.upstream_documentation()->name().empty())
{
std::string value(get(keys, m.upstream_documentation()->name()));
if (! value.empty())
id->load_upstream_documentation(m.upstream_documentation(), value);
}
if (! m.upstream_release_notes()->name().empty())
{
std::string value(get(keys, m.upstream_release_notes()->name()));
if (! value.empty())
id->load_upstream_release_notes(m.upstream_release_notes(), value);
}
if (! m.bugs_to()->name().empty())
{
std::string value(get(keys, m.bugs_to()->name()));
if (! value.empty())
id->load_bugs_to(m.bugs_to(), value);
}
if (! m.remote_ids()->name().empty())
{
std::string value(get(keys, m.remote_ids()->name()));
if (! value.empty())
id->load_remote_ids(m.remote_ids(), value);
}
if (id->eapi()->supported()->is_pbin() && ! m.scm_revision()->name().empty())
{
std::string value(get(keys, m.scm_revision()->name()));
if (! value.empty())
id->load_scm_revision(m.scm_revision()->name(), m.scm_revision()->description(), value);
}
if (! m.defined_phases()->name().empty())
{
std::set<std::string> defined_phases, raw_values, ebuild_functions;
std::string raw_value(get(keys, "PALUDIS_DECLARED_FUNCTIONS"));
tokenise_whitespace(raw_value, std::inserter(raw_values, raw_values.begin()));
tokenise_whitespace(id->eapi()->supported()->ebuild_options()->ebuild_functions(),
std::inserter(ebuild_functions, ebuild_functions.end()));
for (auto function : ebuild_functions)
{
if (0 == function.compare(0, 8, "builtin_"))
continue;
if (raw_values.end() == raw_values.find(function))
continue;
if (0 == function.compare(0, 4, "src_"))
function.erase(0, 4);
else if (0 == function.compare(0, 4, "pkg_"))
function.erase(0, 4);
else
throw InternalError(PALUDIS_HERE, "Got strange phase function '" + function + "'");
defined_phases.insert(function);
}
if (defined_phases.empty())
id->load_defined_phases(m.defined_phases(), "-");
else
id->load_defined_phases(m.defined_phases(), join(defined_phases.begin(), defined_phases.end(), " "));
}
}
EbuildVariableCommand::EbuildVariableCommand(const EbuildCommandParams & p,
const std::string & var) :
EbuildCommand(p),
_var(var)
{
}
std::string
EbuildVariableCommand::commands() const
{
return params.commands();
}
bool
EbuildVariableCommand::failure()
{
return EbuildCommand::failure();
}
void
EbuildVariableCommand::extend_command(Process & process)
{
process
.setenv("PALUDIS_VARIABLE", _var)
.setenv("PALUDIS_EBUILD_QUIET", "yes")
.setuid_setgid(params.environment()->reduced_uid(), params.environment()->reduced_gid());
}
bool
EbuildVariableCommand::do_run_command(Process & process)
{
std::stringstream prog;
process.capture_stdout(prog);
int exit_status(process.run().wait());
_result = strip_trailing_string(
std::string((std::istreambuf_iterator<char>(prog)),
std::istreambuf_iterator<char>()), "\n");
return (0 == exit_status);
}
std::string
EbuildNoFetchCommand::commands() const
{
return params.commands();
}
bool
EbuildNoFetchCommand::failure()
{
throw ActionFailedError("Fetch failed for '" + stringify(*params.package_id()) + "'");
}
void
EbuildNoFetchCommand::extend_command(Process & process)
{
const auto & package_id = params.package_id();
const auto & eapi = package_id->eapi()->supported();
const auto & environment_variables = eapi->ebuild_environment_variables();
process
.setenv("PALUDIS_PROFILE_DIR", stringify(*fetch_params.profiles()->begin()))
.setenv("PALUDIS_PROFILE_DIRS", join(fetch_params.profiles()->begin(),
fetch_params.profiles()->end(), " "))
.setenv("PALUDIS_PROFILES_DIRS", join(fetch_params.profiles_with_parents()->begin(),
fetch_params.profiles_with_parents()->end(), " "))
.setenv("PALUDIS_ARCHIVES_VAR",
environment_variables->env_a());
if (! environment_variables->env_a().empty())
process.setenv(environment_variables->env_a(), fetch_params.a());
if (! environment_variables->env_aa().empty())
process.setenv(environment_variables->env_aa(), fetch_params.aa());
if (! environment_variables->env_use().empty())
process.setenv(environment_variables->env_use(), fetch_params.use());
if (! environment_variables->env_use_expand().empty())
process.setenv(environment_variables->env_use_expand(),
fetch_params.use_expand());
if (! environment_variables->env_use_expand_hidden().empty())
process.setenv(environment_variables->env_use_expand_hidden(),
fetch_params.use_expand_hidden());
for (const auto & kv : *fetch_params.expand_vars())
process.setenv(kv.first, kv.second);
}
EbuildNoFetchCommand::EbuildNoFetchCommand(const EbuildCommandParams & p,
const EbuildNoFetchCommandParams & f) :
EbuildCommand(p),
fetch_params(f)
{
}
std::string
EbuildInstallCommand::commands() const
{
return params.commands();
}
bool
EbuildInstallCommand::failure()
{
throw ActionFailedError("Install failed for '" + stringify(*params.package_id()) + "'");
}
void
EbuildInstallCommand::extend_command(Process & process)
{
const auto & package_id = params.package_id();
const auto & eapi = package_id->eapi()->supported();
const auto & environment_variables = eapi->ebuild_environment_variables();
process
.setenv("PALUDIS_LOADSAVEENV_DIR", stringify(install_params.loadsaveenv_dir()))
.setenv("PALUDIS_CONFIG_PROTECT", install_params.config_protect())
.setenv("PALUDIS_CONFIG_PROTECT_MASK", install_params.config_protect_mask())
.setenv("PALUDIS_PROFILE_DIR", stringify(*install_params.profiles()->begin()))
.setenv("PALUDIS_PROFILE_DIRS", join(install_params.profiles()->begin(),
install_params.profiles()->end(), " "))
.setenv("PALUDIS_PROFILES_DIRS", join(install_params.profiles_with_parents()->begin(),
install_params.profiles_with_parents()->end(), " "))
.setenv("PALUDIS_ARCHIVES_VAR",
eapi->ebuild_environment_variables()->env_a())
.setenv("SLOT", stringify(install_params.slot()));
if (! environment_variables->env_a().empty())
process.setenv(environment_variables->env_a(), install_params.a());
if (! environment_variables->env_aa().empty())
process.setenv(environment_variables->env_aa(), install_params.aa());
if (! environment_variables->env_accept_license().empty())
process.setenv(environment_variables->env_accept_license(),
install_params.accept_license());
if (! environment_variables->env_use().empty())
process.setenv(environment_variables->env_use(), install_params.use());
if (! environment_variables->env_use_expand().empty())
process.setenv(environment_variables->env_use_expand(),
install_params.use_expand());
if (! environment_variables->env_use_expand_hidden().empty())
process.setenv(environment_variables->env_use_expand_hidden(),
install_params.use_expand_hidden());
if (! environment_variables->env_replacing_ids().empty())
process.setenv(environment_variables->env_replacing_ids(),
join(indirect_iterator(install_params.replacing_ids()->begin()),
indirect_iterator(install_params.replacing_ids()->end()), " "));
if (! environment_variables->env_replacing_versions().empty())
{
std::string s;
for (const auto & id : *install_params.replacing_ids())
if (id->name() == params.package_id()->name())
{
if (! s.empty())
s.append(" ");
s.append(stringify(id->version()));
}
process.setenv(environment_variables->env_replacing_versions(), s);
}
if (! environment_variables->env_merge_type().empty())
{
std::string s;
if (install_params.destination())
{
if (install_params.destination()->installed_root_key())
{
if (install_params.is_from_pbin())
s = "binary";
else
s = "source";
}
else
s = "buildonly";
}
process.setenv(environment_variables->env_merge_type(), s);
}
for (const auto & kv : *install_params.expand_vars())
process.setenv(kv.first, kv.second);
}
EbuildInstallCommand::EbuildInstallCommand(const EbuildCommandParams & p,
const EbuildInstallCommandParams & f) :
EbuildCommand(p),
install_params(f)
{
}
std::string
EbuildUninstallCommand::commands() const
{
return params.commands();
}
std::string
EbuildUninstallCommand::ebuild_file() const
{
return "-";
}
bool
EbuildUninstallCommand::failure()
{
throw ActionFailedError("Uninstall failed for '" + stringify(*params.package_id()) + "'");
}
void
EbuildUninstallCommand::extend_command(Process & process)
{
const auto & package_id = params.package_id();
const auto & eapi = package_id->eapi()->supported();
const auto & environment_variables = eapi->ebuild_environment_variables();
process
.setenv("PALUDIS_LOADSAVEENV_DIR", stringify(uninstall_params.loadsaveenv_dir()));
if (uninstall_params.load_environment())
process
.setenv("PALUDIS_LOAD_ENVIRONMENT", stringify(*uninstall_params.load_environment()))
.setenv("PALUDIS_SKIP_INHERIT", "yes");
if (! environment_variables->env_replaced_by_id().empty())
if (uninstall_params.replaced_by())
process.setenv(environment_variables->env_replaced_by_id(),
stringify(*uninstall_params.replaced_by()));
if (! environment_variables->env_replaced_by_version().empty())
if (uninstall_params.replaced_by())
process.setenv(environment_variables->env_replaced_by_version(),
stringify(uninstall_params.replaced_by()->version()));
}
EbuildUninstallCommand::EbuildUninstallCommand(const EbuildCommandParams & p,
const EbuildUninstallCommandParams & f) :
EbuildCommand(p),
uninstall_params(f)
{
}
std::string
EbuildConfigCommand::ebuild_file() const
{
return "-";
}
std::string
EbuildConfigCommand::commands() const
{
return params.commands();
}
bool
EbuildConfigCommand::failure()
{
throw ActionFailedError("Configure failed for '" + stringify(*params.package_id()) + "'");
}
void
EbuildConfigCommand::extend_command(Process & process)
{
if (config_params.load_environment())
process
.setenv("PALUDIS_LOAD_ENVIRONMENT", stringify(*config_params.load_environment()))
.setenv("PALUDIS_SKIP_INHERIT", "yes");
}
EbuildConfigCommand::EbuildConfigCommand(const EbuildCommandParams & p,
const EbuildConfigCommandParams & f) :
EbuildCommand(p),
config_params(f)
{
}
WriteVDBEntryCommand::WriteVDBEntryCommand(const WriteVDBEntryParams & p) :
params(p)
{
}
void
WriteVDBEntryCommand::operator() ()
{
using namespace std::placeholders;
const auto & package_id = params.package_id();
const auto & eapi = package_id->eapi()->supported();
std::string ebuild_cmd(getenv_with_default(env_vars::ebuild_dir, LIBEXECDIR "/paludis") +
"/write_vdb_entry.bash '" +
stringify(params.output_directory()) + "' '" +
stringify(params.environment_file()) + "'");
std::shared_ptr<const FSPathSequence> syncers_dirs(params.environment()->syncers_dirs());
std::shared_ptr<const FSPathSequence> bashrc_files(params.environment()->bashrc_files());
std::shared_ptr<const FSPathSequence> fetchers_dirs(params.environment()->fetchers_dirs());
std::shared_ptr<const FSPathSequence> hook_dirs(params.environment()->hook_dirs());
Process process((ProcessCommand(ebuild_cmd)));
process
.setenv("PKGMANAGER", PALUDIS_PACKAGE "-" + stringify(PALUDIS_VERSION_MAJOR) + "." +
stringify(PALUDIS_VERSION_MINOR) + "." +
stringify(PALUDIS_VERSION_MICRO) +
(std::string(PALUDIS_GIT_HEAD).empty() ?
std::string("") : "-git-" + std::string(PALUDIS_GIT_HEAD)))
.setenv("EAPI", stringify(params.package_id()->eapi()->exported_name()))
.setenv("PALUDIS_CONFIG_DIR", SYSCONFDIR "/paludis/")
.setenv("PALUDIS_BASHRC_FILES", join(bashrc_files->begin(), bashrc_files->end(), " "))
.setenv("PALUDIS_HOOK_DIRS", join(hook_dirs->begin(), hook_dirs->end(), " "))
.setenv("PALUDIS_FETCHERS_DIRS", join(fetchers_dirs->begin(), fetchers_dirs->end(), " "))
.setenv("PALUDIS_SYNCERS_DIRS", join(syncers_dirs->begin(), syncers_dirs->end(), " "))
.setenv("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
.setenv("PALUDIS_EBUILD_DIR", getenv_with_default(env_vars::ebuild_dir, LIBEXECDIR "/paludis"))
.setenv("PALUDIS_VDB_FROM_ENV_VARIABLES",
eapi->ebuild_options()->vdb_from_env_variables())
.setenv("PALUDIS_VDB_FROM_ENV_UNLESS_EMPTY_VARIABLES",
eapi->ebuild_options()->vdb_from_env_unless_empty_variables())
.setenv("PALUDIS_F_FUNCTION_PREFIX",
eapi->ebuild_options()->f_function_prefix())
.setenv("PALUDIS_IGNORE_PIVOT_ENV_FUNCTIONS",
eapi->ebuild_options()->ignore_pivot_env_functions())
.setenv("PALUDIS_IGNORE_PIVOT_ENV_VARIABLES",
eapi->ebuild_options()->ignore_pivot_env_variables())
.setenv("PALUDIS_EBUILD_MODULE_SUFFIXES",
eapi->ebuild_options()->ebuild_module_suffixes())
.setenv("PALUDIS_EBUILD_PHASE_VAR",
eapi->ebuild_environment_variables()->env_ebuild_phase())
.setenv("PALUDIS_EBUILD_PHASE_FUNC_VAR",
eapi->ebuild_environment_variables()->env_ebuild_phase_func())
.setenv("PALUDIS_PIPE_COMMANDS_SUPPORTED", "yes")
.setenv("PALUDIS_PIPE_COMMANDS_STATUS_SUPPORTED", "yes")
.pipe_command_handler("PALUDIS_PIPE_COMMAND",
std::bind(&pipe_command_handler,
params.environment(),
params.package_id(),
nullptr,
nullptr,
nullptr, false, _1,
params.maybe_output_manager()));
if (! eapi->ebuild_metadata_variables()->iuse_effective()->name().empty())
if (package_id->raw_iuse_effective_key())
{
auto iu(package_id->raw_iuse_effective_key()->parse_value());
process.setenv(eapi->ebuild_metadata_variables()->iuse_effective()->name(),
join(iu->begin(), iu->end(), " "));
}
if (! eapi->ebuild_metadata_variables()->scm_revision()->name().empty())
if (package_id->scm_revision_key())
process.setenv(eapi->ebuild_metadata_variables()->scm_revision()->name(),
package_id->scm_revision_key()->parse_value());;
if (params.maybe_output_manager())
process
.capture_stderr(params.maybe_output_manager()->stderr_stream())
.capture_stdout(params.maybe_output_manager()->stdout_stream())
.use_ptys();
std::string defined_phases(eapi->ebuild_metadata_variables()->defined_phases()->name());
if (! defined_phases.empty())
if (package_id->defined_phases_key())
{
auto dp(package_id->defined_phases_key()->parse_value());
process.setenv(defined_phases, join(dp->begin(), dp->end(), " "));
}
if (0 != process.run().wait())
throw ActionFailedError("Write VDB Entry command failed");
}
VDBPostMergeUnmergeCommand::VDBPostMergeUnmergeCommand(const VDBPostMergeUnmergeCommandParams & p) :
params(p)
{
}
void
VDBPostMergeUnmergeCommand::operator() ()
{
if (! getenv_with_default("PALUDIS_NO_GLOBAL_HOOKS", "").empty())
return;
Process process(ProcessCommand({ getenv_with_default(env_vars::ebuild_dir, LIBEXECDIR "/paludis") + "/utils/wrapped_ldconfig",
stringify(params.root()) }));
if (0 != process.run().wait())
throw ActionFailedError("VDB Entry post merge commands failed");
}
std::string
EbuildPretendCommand::commands() const
{
return params.commands();
}
bool
EbuildPretendCommand::failure()
{
return false;
}
void
EbuildPretendCommand::extend_command(Process & process)
{
const auto & package_id = params.package_id();
const auto & eapi = package_id->eapi()->supported();
const auto & environment_variables = eapi->ebuild_environment_variables();
process
.extra_newlines_if_any_output_exists()
.prefix_stdout(stringify(package_id->name().package()) + "-" +
stringify(package_id->version()) + "> ")
.prefix_stderr(stringify(package_id->name().package()) + "-" +
stringify(package_id->version()) + "> ")
.setenv("PALUDIS_EBUILD_QUIET", "yes")
.setenv("PALUDIS_PROFILE_DIR", stringify(*pretend_params.profiles()->begin()))
.setenv("PALUDIS_PROFILE_DIRS", join(pretend_params.profiles()->begin(),
pretend_params.profiles()->end(), " "))
.setenv("PALUDIS_PROFILES_DIRS", join(pretend_params.profiles_with_parents()->begin(),
pretend_params.profiles_with_parents()->end(), " "));
if (! environment_variables->env_use().empty())
process.setenv(environment_variables->env_use(), pretend_params.use());
if (! environment_variables->env_use_expand().empty())
process.setenv(environment_variables->env_use_expand(), pretend_params.use_expand());
if (! environment_variables->env_use_expand_hidden().empty())
process.setenv(environment_variables->env_use_expand_hidden(), pretend_params.use_expand_hidden());
if (! environment_variables->env_replacing_ids().empty())
process.setenv(environment_variables->env_replacing_ids(),
join(indirect_iterator(pretend_params.replacing_ids()->begin()),
indirect_iterator(pretend_params.replacing_ids()->end()), " "));
if (! environment_variables->env_replacing_versions().empty())
{
std::string s;
for (const auto & id : *pretend_params.replacing_ids())
{
if (id->name() == params.package_id()->name())
{
if (! s.empty())
s.append(" ");
s.append(stringify(id->version()));
}
}
process.setenv(environment_variables->env_replacing_versions(), s);
}
for (const auto & kv : *pretend_params.expand_vars())
process.setenv(kv.first, kv.second);
process.setuid_setgid(params.environment()->reduced_uid(), params.environment()->reduced_gid());
}
EbuildPretendCommand::EbuildPretendCommand(const EbuildCommandParams & p,
const EbuildPretendCommandParams & f) :
EbuildCommand(p),
pretend_params(f)
{
}
std::string
EbuildInfoCommand::ebuild_file() const
{
if (info_params.use_ebuild_file())
return stringify(params.ebuild_file());
else
return "-";
}
std::string
EbuildInfoCommand::commands() const
{
return params.commands();
}
bool
EbuildInfoCommand::failure()
{
throw ActionFailedError("Info command failed");
}
void
EbuildInfoCommand::extend_command(Process & process)
{
const auto & package_id = params.package_id();
const auto & eapi = package_id->eapi()->supported();
const auto & environment_variables = eapi->ebuild_environment_variables();
std::string info_vars(join(info_params.info_vars()->begin(), info_params.info_vars()->end(), " "));
process
.prefix_stdout(" ")
.prefix_stderr(" ")
.setenv("PALUDIS_INFO_VARS", info_vars)
.setenv("PALUDIS_PROFILE_DIR",
info_params.profiles()->empty() ? std::string("") : stringify(*info_params.profiles()->begin()))
.setenv("PALUDIS_PROFILE_DIRS", join(info_params.profiles()->begin(),
info_params.profiles()->end(), " "))
.setenv("PALUDIS_PROFILES_DIRS", join(info_params.profiles_with_parents()->begin(),
info_params.profiles_with_parents()->end(), " "));
if (! environment_variables->env_use().empty())
process.setenv(environment_variables->env_use(), info_params.use());
if (! environment_variables->env_use_expand().empty())
process.setenv(environment_variables->env_use_expand(), info_params.use_expand());
if (! environment_variables->env_use_expand_hidden().empty())
process.setenv(environment_variables->env_use_expand_hidden(), info_params.use_expand_hidden());
for (const auto & kv : *info_params.expand_vars())
process.setenv(kv.first, kv.second);
process.setuid_setgid(params.environment()->reduced_uid(), params.environment()->reduced_gid());
if (info_params.load_environment())
process
.setenv("PALUDIS_LOAD_ENVIRONMENT", stringify(*info_params.load_environment()))
.setenv("PALUDIS_SKIP_INHERIT", "yes");
}
EbuildInfoCommand::EbuildInfoCommand(const EbuildCommandParams & p,
const EbuildInfoCommandParams & f) :
EbuildCommand(p),
info_params(f)
{
}
WriteBinaryEbuildCommand::WriteBinaryEbuildCommand(const WriteBinaryEbuildCommandParams & p) :
params(p)
{
}
void
WriteBinaryEbuildCommand::operator() ()
{
using namespace std::placeholders;
const auto & package_id = params.package_id();
const auto & eapi = package_id->eapi()->supported();
if (! EAPIData::get_instance()->eapi_from_string("pbin-1+" + package_id->eapi()->exported_name())->supported())
throw ActionFailedError("Don't know how to write binary ebuilds using EAPI 'pbin-1+" +
package_id->eapi()->exported_name());
std::string ebuild_cmd(getenv_with_default(env_vars::ebuild_dir, LIBEXECDIR "/paludis") +
"/write_binary_ebuild.bash '" +
stringify(params.binary_ebuild_location()) + "' '" +
stringify(params.binary_distdir() / params.binary_dist_base()) + "' '" +
stringify(params.environment_file()) + "' '" +
stringify(params.image()) + "'");
std::shared_ptr<const FSPathSequence> syncers_dirs(params.environment()->syncers_dirs());
std::shared_ptr<const FSPathSequence> bashrc_files(params.environment()->bashrc_files());
std::shared_ptr<const FSPathSequence> fetchers_dirs(params.environment()->fetchers_dirs());
std::shared_ptr<const FSPathSequence> hook_dirs(params.environment()->hook_dirs());
Process process((ProcessCommand(ebuild_cmd)));
process
.setenv("PKGMANAGER", PALUDIS_PACKAGE "-" + stringify(PALUDIS_VERSION_MAJOR) + "." +
stringify(PALUDIS_VERSION_MINOR) + "." +
stringify(PALUDIS_VERSION_MICRO) +
(std::string(PALUDIS_GIT_HEAD).empty() ?
std::string("") : "-git-" + std::string(PALUDIS_GIT_HEAD)))
.setenv("EAPI", stringify(package_id->eapi()->exported_name()))
.setenv("PALUDIS_CONFIG_DIR", SYSCONFDIR "/paludis/")
.setenv("PALUDIS_TMPDIR", stringify(params.builddir()))
.setenv("PALUDIS_BASHRC_FILES", join(bashrc_files->begin(), bashrc_files->end(), " "))
.setenv("PALUDIS_HOOK_DIRS", join(hook_dirs->begin(), hook_dirs->end(), " "))
.setenv("PALUDIS_FETCHERS_DIRS", join(fetchers_dirs->begin(), fetchers_dirs->end(), " "))
.setenv("PALUDIS_SYNCERS_DIRS", join(syncers_dirs->begin(), syncers_dirs->end(), " "))
.setenv("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
.setenv("PALUDIS_EBUILD_DIR", getenv_with_default(env_vars::ebuild_dir, LIBEXECDIR "/paludis"))
.setenv("PALUDIS_BINARY_FROM_ENV_VARIABLES",
eapi->ebuild_options()->binary_from_env_variables())
.setenv("PALUDIS_F_FUNCTION_PREFIX",
eapi->ebuild_options()->f_function_prefix())
.setenv("PALUDIS_IGNORE_PIVOT_ENV_FUNCTIONS",
eapi->ebuild_options()->ignore_pivot_env_functions())
.setenv("PALUDIS_IGNORE_PIVOT_ENV_VARIABLES",
eapi->ebuild_options()->ignore_pivot_env_variables())
.setenv("PALUDIS_BINARY_URI_PREFIX", params.destination_repository()->params().binary_uri_prefix())
.setenv("PALUDIS_BINARY_KEYWORDS", params.binary_keywords())
.setenv("PALUDIS_BINARY_KEYWORDS_VARIABLE", EAPIData::get_instance()->eapi_from_string("pbin-1+"
+ package_id->eapi()->exported_name())->supported()->ebuild_metadata_variables()->keywords()->name())
.setenv("PALUDIS_BINARY_DISTDIR_VARIABLE", EAPIData::get_instance()->eapi_from_string("pbin-1+"
+ package_id->eapi()->exported_name())->supported()->ebuild_environment_variables()->env_distdir())
.setenv("PALUDIS_BINARY_URI_EXTENSION", params.binary_uri_extension())
.setenv("PALUDIS_EBUILD_MODULE_SUFFIXES",
eapi->ebuild_options()->ebuild_module_suffixes())
.setenv("PALUDIS_EBUILD_PHASE_VAR",
eapi->ebuild_environment_variables()->env_ebuild_phase())
.setenv("PALUDIS_EBUILD_PHASE_FUNC_VAR",
eapi->ebuild_environment_variables()->env_ebuild_phase_func())
.setenv("PALUDIS_PIPE_COMMANDS_SUPPORTED", "yes")
.setenv("PALUDIS_PIPE_COMMANDS_STATUS_SUPPORTED", "yes")
.pipe_command_handler("PALUDIS_PIPE_COMMAND",
std::bind(&pipe_command_handler,
params.environment(),
package_id,
nullptr,
nullptr,
nullptr,
false, _1,
params.maybe_output_manager()));
if (! eapi->ebuild_metadata_variables()->scm_revision()->name().empty())
if (package_id->scm_revision_key())
process.setenv(eapi->ebuild_metadata_variables()->scm_revision()->name(),
package_id->scm_revision_key()->parse_value());;
if (0 != process.run().wait())
throw ActionFailedError("Write binary command failed");
}
std::string
EbuildBadOptionsCommand::commands() const
{
return params.commands();
}
bool
EbuildBadOptionsCommand::failure()
{
return false;
}
void
EbuildBadOptionsCommand::extend_command(Process & process)
{
const auto & package_id = params.package_id();
const auto & eapi = package_id->eapi()->supported();
const auto & environment_variables = eapi->ebuild_environment_variables();
process
.setenv("PALUDIS_EBUILD_QUIET", "yes")
.setenv("PALUDIS_PROFILE_DIR", stringify(*bad_options_params.profiles()->begin()))
.setenv("PALUDIS_PROFILE_DIRS", join(bad_options_params.profiles()->begin(),
bad_options_params.profiles()->end(), " "))
.setenv("PALUDIS_PROFILES_DIRS", join(bad_options_params.profiles_with_parents()->begin(),
bad_options_params.profiles_with_parents()->end(), " "))
.setenv("EX_UNMET_REQUIREMENTS", join(bad_options_params.unmet_requirements()->begin(),
bad_options_params.unmet_requirements()->end(), "\n"));
if (! environment_variables->env_use().empty())
process.setenv(environment_variables->env_use(), bad_options_params.use());
if (! environment_variables->env_use_expand().empty())
process.setenv(environment_variables->env_use_expand(), bad_options_params.use_expand());
if (! environment_variables->env_use_expand_hidden().empty())
process.setenv(environment_variables->env_use_expand_hidden(), bad_options_params.use_expand_hidden());
for (const auto & kv : *bad_options_params.expand_vars())
process.setenv(kv.first, kv.second);
process.setuid_setgid(params.environment()->reduced_uid(), params.environment()->reduced_gid());
}
EbuildBadOptionsCommand::EbuildBadOptionsCommand(const EbuildCommandParams & p,
const EbuildBadOptionsCommandParams & f) :
EbuildCommand(p),
bad_options_params(f)
{
}
std::string
EbuildFetchExtraCommand::commands() const
{
return params.commands();
}
bool
EbuildFetchExtraCommand::failure()
{
throw ActionFailedError("Extra fetch failed for '" + stringify(*params.package_id()) + "'");
}
void
EbuildFetchExtraCommand::extend_command(Process & process)
{
const auto & package_id = params.package_id();
const auto & eapi = package_id->eapi()->supported();
const auto & environment_variables = eapi->ebuild_environment_variables();
process
.setenv("PALUDIS_LOADSAVEENV_DIR", stringify(fetch_extra_params.loadsaveenv_dir()))
.setenv("PALUDIS_PROFILE_DIR", stringify(*fetch_extra_params.profiles()->begin()))
.setenv("PALUDIS_PROFILE_DIRS", join(fetch_extra_params.profiles()->begin(),
fetch_extra_params.profiles()->end(), " "))
.setenv("PALUDIS_PROFILES_DIRS", join(fetch_extra_params.profiles_with_parents()->begin(),
fetch_extra_params.profiles_with_parents()->end(), " "))
.setenv("PALUDIS_ARCHIVES_VAR", environment_variables->env_a())
.setenv("SLOT", stringify(fetch_extra_params.slot()));
if (! environment_variables->env_a().empty())
process.setenv(environment_variables->env_a(), fetch_extra_params.a());
if (! environment_variables->env_aa().empty())
process.setenv(environment_variables->env_aa(), fetch_extra_params.aa());
if (! environment_variables->env_use().empty())
process.setenv(environment_variables->env_use(), fetch_extra_params.use());
if (! environment_variables->env_use_expand().empty())
process.setenv(environment_variables->env_use_expand(), fetch_extra_params.use_expand());
if (! environment_variables->env_use_expand_hidden().empty())
process.setenv(environment_variables->env_use_expand_hidden(), fetch_extra_params.use_expand_hidden());
for (const auto & kv : *fetch_extra_params.expand_vars())
process.setenv(kv.first, kv.second);
}
EbuildFetchExtraCommand::EbuildFetchExtraCommand(const EbuildCommandParams & p,
const EbuildFetchExtraCommandParams & f) :
EbuildCommand(p),
fetch_extra_params(f)
{
}