diff options
47 files changed, 1654 insertions, 53 deletions
diff --git a/paludis/dep_list/dep_list.cc b/paludis/dep_list/dep_list.cc index 2a1e648cd..1bc091dcc 100644 --- a/paludis/dep_list/dep_list.cc +++ b/paludis/dep_list/dep_list.cc @@ -123,6 +123,7 @@ namespace .ebuild_interface(0) .deps_interface(0) .origins_interface(0) + .ebin_interface(0) .license_interface(0)), VersionMetadataVirtualInterface(e) { diff --git a/paludis/repositories/cran/cran_version_metadata.cc b/paludis/repositories/cran/cran_version_metadata.cc index c110697e2..bcfb525f1 100644 --- a/paludis/repositories/cran/cran_version_metadata.cc +++ b/paludis/repositories/cran/cran_version_metadata.cc @@ -32,6 +32,7 @@ CRANVersionMetadata::CRANVersionMetadata(bool want_origins) : .virtual_interface(0) .origins_interface(want_origins ? _origins : 0) .deps_interface(this) + .ebin_interface(0) ), VersionMetadataCRANInterface("", "", "", false, false), VersionMetadataDepsInterface(CRANDepParser::parse), diff --git a/paludis/repositories/fake/fake_repository_base.cc b/paludis/repositories/fake/fake_repository_base.cc index 7a162f6f4..7bdff8bf1 100644 --- a/paludis/repositories/fake/fake_repository_base.cc +++ b/paludis/repositories/fake/fake_repository_base.cc @@ -312,6 +312,7 @@ FakeVersionMetadata::FakeVersionMetadata() : .cran_interface(0) .virtual_interface(0) .origins_interface(0) + .ebin_interface(0) ), VersionMetadataEbuildInterface(), VersionMetadataDepsInterface(&PortageDepParser::parse_depend), @@ -334,6 +335,7 @@ FakeVirtualVersionMetadata::FakeVirtualVersionMetadata(const SlotName & s, const .cran_interface(0) .virtual_interface(this) .origins_interface(0) + .ebin_interface(0) ), VersionMetadataDepsInterface(&PortageDepParser::parse_depend), VersionMetadataVirtualInterface(p) diff --git a/paludis/repositories/gems/gems_version_metadata.cc b/paludis/repositories/gems/gems_version_metadata.cc index 96e40813c..c07397d09 100644 --- a/paludis/repositories/gems/gems_version_metadata.cc +++ b/paludis/repositories/gems/gems_version_metadata.cc @@ -32,6 +32,7 @@ GemsVersionMetadata::GemsVersionMetadata(const VersionSpec & v) : .virtual_interface(0) .origins_interface(0) .license_interface(0) + .ebin_interface(0) ), VersionMetadataDepsInterface(&PortageDepParser::parse_depend) { diff --git a/paludis/repositories/gentoo/Makefile.am b/paludis/repositories/gentoo/Makefile.am index a9e139a18..20a577848 100644 --- a/paludis/repositories/gentoo/Makefile.am +++ b/paludis/repositories/gentoo/Makefile.am @@ -6,6 +6,7 @@ DISTCLEANFILES = \ portage_repository_params-sr.hh portage_repository_params-sr.cc \ vdb_repository-sr.hh vdb_repository-sr.cc \ ebuild-sr.hh ebuild-sr.cc ebuild-se.hh ebuild-se.cc \ + ebin-sr.hh ebin-sr.cc ebin-se.hh ebin-se.cc \ vdb_merger-sr.hh vdb_merger-sr.cc \ vdb_unmerger-sr.hh vdb_unmerger-sr.cc @@ -54,6 +55,9 @@ paludis_repositories_gentoo_include_HEADERS = \ ebuild.hh \ ebuild-sr.hh \ ebuild-se.hh \ + ebin.hh \ + ebin-se.hh \ + ebin-sr.hh \ glsa.hh \ glsa-sr.hh \ portage_repository-sr.hh \ @@ -67,9 +71,11 @@ paludis_repositories_gentoo_include_HEADERS = \ portage_repository_sets.hh \ portage_repository_entries.hh \ ebuild_entries.hh \ + ebin_entries.hh \ ebuild_flat_metadata_cache.hh \ eclass_mtimes.hh \ make_ebuild_repository.hh \ + make_ebin_repository.hh \ use_desc.hh \ portage_virtual_version_metadata.hh \ vdb_repository.hh \ @@ -82,6 +88,7 @@ paludis_repositories_gentoo_include_HEADERS = \ libpaludisgentoorepository_la_SOURCES = \ ebuild.cc \ + ebin.cc \ glsa.cc \ portage_repository.cc \ portage_repository_profile_file.cc \ @@ -91,10 +98,12 @@ libpaludisgentoorepository_la_SOURCES = \ portage_repository_sets.cc \ portage_repository_entries.cc \ ebuild_entries.cc \ + ebin_entries.cc \ ebuild_flat_metadata_cache.cc \ eclass_mtimes.cc \ portage_repository_params.cc \ make_ebuild_repository.cc \ + make_ebin_repository.cc \ use_desc.cc \ portage_virtual_version_metadata.cc \ registration.cc \ @@ -158,6 +167,12 @@ EXTRA_DIST = \ ebuild.se \ ebuild-se.hh \ ebuild-se.cc \ + ebin.sr \ + ebin-sr.hh \ + ebin-sr.cc \ + ebin.se \ + ebin-se.hh \ + ebin-se.cc \ glsa.sr \ glsa-sr.hh \ glsa-sr.cc \ @@ -199,6 +214,10 @@ BUILT_SOURCES = \ ebuild-sr.cc \ ebuild-se.hh \ ebuild-se.cc \ + ebin-sr.hh \ + ebin-sr.cc \ + ebin-se.hh \ + ebin-se.cc \ vdb_merger-sr.hh \ vdb_merger-sr.cc \ vdb_unmerger-sr.hh \ @@ -248,6 +267,12 @@ ebuild-sr.hh : ebuild.sr $(top_srcdir)/misc/make_sr.bash ebuild-sr.cc : ebuild.sr $(top_srcdir)/misc/make_sr.bash $(top_srcdir)/misc/make_sr.bash --source $(srcdir)/ebuild.sr > $@ +ebin-sr.hh : ebin.sr $(top_srcdir)/misc/make_sr.bash + $(top_srcdir)/misc/make_sr.bash --header $(srcdir)/ebin.sr > $@ + +ebin-sr.cc : ebin.sr $(top_srcdir)/misc/make_sr.bash + $(top_srcdir)/misc/make_sr.bash --source $(srcdir)/ebin.sr > $@ + glsa-sr.hh : glsa.sr $(top_srcdir)/misc/make_sr.bash $(top_srcdir)/misc/make_sr.bash --header $(srcdir)/glsa.sr > $@ @@ -266,6 +291,12 @@ ebuild-se.hh : ebuild.se $(top_srcdir)/misc/make_se.bash ebuild-se.cc : ebuild.se $(top_srcdir)/misc/make_se.bash if ! $(top_srcdir)/misc/make_se.bash --source $(srcdir)/ebuild.se > $@ ; then rm -f $@ ; exit 1 ; fi +ebin-se.hh : ebin.se $(top_srcdir)/misc/make_se.bash + if ! $(top_srcdir)/misc/make_se.bash --header $(srcdir)/ebin.se > $@ ; then rm -f $@ ; exit 1 ; fi + +ebin-se.cc : ebin.se $(top_srcdir)/misc/make_se.bash + if ! $(top_srcdir)/misc/make_se.bash --source $(srcdir)/ebin.se > $@ ; then rm -f $@ ; exit 1 ; fi + libpaludisgentoorepositoryxmlthings_la_SOURCES = xml_things.cc xml_things.hh libpaludisgentoorepositoryxmlthings_la_CXXFLAGS = $(AM_CXXFLAGS) @LIBXML2DEPS_CFLAGS@ diff --git a/paludis/repositories/gentoo/ebin.cc b/paludis/repositories/gentoo/ebin.cc new file mode 100644 index 000000000..314e74f5d --- /dev/null +++ b/paludis/repositories/gentoo/ebin.cc @@ -0,0 +1,290 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * 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 "ebin.hh" +#include <paludis/portage_dep_parser.hh> +#include <paludis/environment.hh> +#include <paludis/util/system.hh> +#include <paludis/util/log.hh> +#include <paludis/util/strip.hh> +#include <paludis/about.hh> + +using namespace paludis; + +#include <paludis/repositories/gentoo/ebin-se.cc> +#include <paludis/repositories/gentoo/ebin-sr.cc> + +EbinVersionMetadata::EbinVersionMetadata(const SlotName & s) : + VersionMetadata( + VersionMetadataBase(s, "", "", "paludis-1"), + VersionMetadataCapabilities::create() + .ebin_interface(this) + .ebuild_interface(this) + .deps_interface(this) + .license_interface(this) + .origins_interface(this) + .cran_interface(0) + .virtual_interface(0) + ), + VersionMetadataDepsInterface(&PortageDepParser::parse_depend), + VersionMetadataLicenseInterface(&PortageDepParser::parse_license) +{ +} + +EbinVersionMetadata::~EbinVersionMetadata() +{ +} + +EbinCommand::EbinCommand(const EbinCommandParams & p) : + params(p) +{ +} + +EbinCommand::~EbinCommand() +{ +} + +bool +EbinCommand::success() +{ + return true; +} + +bool +EbinCommand::use_sandbox() const +{ + return true; +} + +bool +EbinCommand::do_run_command(const Command & cmd) +{ + return 0 == run_command(cmd); +} + +bool +EbinCommand::operator() () +{ + Command cmd(getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis") + + "/ebuild.bash '-' " + commands()); + + if (use_sandbox()) + cmd.with_sandbox(); + + cmd = extend_command(cmd + .with_setenv("P", stringify(params.db_entry->name.package) + "-" + + stringify(params.db_entry->version.remove_revision())) + .with_setenv("PV", stringify(params.db_entry->version.remove_revision())) + .with_setenv("PR", stringify(params.db_entry->version.revision_only())) + .with_setenv("PN", stringify(params.db_entry->name.package)) + .with_setenv("PVR", stringify(params.db_entry->version)) + .with_setenv("PF", stringify(params.db_entry->name.package) + "-" + + stringify(params.db_entry->version)) + .with_setenv("CATEGORY", stringify(params.db_entry->name.category)) + .with_setenv("REPOSITORY", stringify(params.db_entry->repository)) + .with_setenv("PORTDIR", stringify(params.portdir)) + .with_setenv("PKGDIR", stringify(params.pkgdir)) + .with_setenv("PKGMANAGER", PALUDIS_PACKAGE "-" + stringify(PALUDIS_VERSION_MAJOR) + "." + + stringify(PALUDIS_VERSION_MINOR) + "." + + stringify(PALUDIS_VERSION_MICRO) + + (std::string(PALUDIS_SUBVERSION_REVISION).empty() ? + std::string("") : "-r" + std::string(PALUDIS_SUBVERSION_REVISION))) + .with_setenv("PALUDIS_TMPDIR", stringify(params.buildroot)) + .with_setenv("PALUDIS_CONFIG_DIR", SYSCONFDIR "/paludis/") + .with_setenv("PALUDIS_BASHRC_FILES", params.environment->bashrc_files()) + .with_setenv("PALUDIS_HOOK_DIRS", params.environment->hook_dirs()) + .with_setenv("PALUDIS_FETCHERS_DIRS", params.environment->fetchers_dirs()) + .with_setenv("PALUDIS_SYNCERS_DIRS", params.environment->syncers_dirs()) + .with_setenv("PALUDIS_COMMAND", params.environment->paludis_command()) + .with_setenv("KV", kernel_version()) + .with_setenv("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level())) + .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))); + + if (do_run_command(cmd)) + return success(); + else + return failure(); +} + +EbinFetchCommand::EbinFetchCommand(const EbinCommandParams & p, const EbinFetchCommandParams & f) : + EbinCommand(p), + fetch_params(f) +{ +} + +std::string +EbinFetchCommand::commands() const +{ + return "fetchbin"; +} + +bool +EbinFetchCommand::failure() +{ + throw PackageFetchActionError("Fetch failed for '" + stringify( + *params.db_entry) + "'"); +} + +Command +EbinFetchCommand::extend_command(const Command & cmd) +{ + return Command(cmd) + .with_setenv("B", fetch_params.b) + .with_setenv("FLAT_BIN_URI", fetch_params.flat_bin_uri) + .with_setenv("ROOT", fetch_params.root) + .with_setenv("PALUDIS_USE_SAFE_RESUME", fetch_params.safe_resume ? "oohyesplease" : ""); +} + +std::string +EbinInstallCommand::commands() const +{ + switch (install_params.phase) + { + case ebin_ip_unpack: + return "initbin unpackbin"; + + case ebin_ip_preinstall: + return "preinst saveenv"; + + case ebin_ip_postinstall: + return "loadenv postinst"; + + case ebin_ip_tidyup: + return "tidyup"; + + case last_ebin_ip: + ; + } + + throw InternalError(PALUDIS_HERE, "Bad phase"); +} + +bool +EbinInstallCommand::failure() +{ + throw PackageInstallActionError("Install failed for '" + stringify( + *params.db_entry) + "'"); +} + +Command +EbinInstallCommand::extend_command(const Command & cmd) +{ + std::string debug_build; + do + { + switch (install_params.debug_build) + { + case ido_none: + debug_build = "none"; + continue; + + case ido_split: + debug_build = "split"; + continue; + + case ido_internal: + debug_build = "internal"; + continue; + } + + throw InternalError(PALUDIS_HERE, "Bad debug_build value"); + } + while (false); + + Command result(Command(cmd) + .with_setenv("B", install_params.b) + .with_setenv("ROOT", install_params.root) + .with_setenv("PALUDIS_LOADSAVEENV_DIR", stringify(install_params.loadsaveenv_dir)) + .with_setenv("PALUDIS_CONFIG_PROTECT", install_params.config_protect) + .with_setenv("PALUDIS_CONFIG_PROTECT_MASK", install_params.config_protect_mask) + .with_setenv("PALUDIS_EBUILD_OVERRIDE_CONFIG_PROTECT_MASK", + install_params.disable_cfgpro ? "/" : "") + .with_setenv("PALUDIS_DEBUG_BUILD", debug_build) + .with_setenv("SLOT", stringify(install_params.slot))); + + switch (install_params.phase) + { + case ebin_ip_preinstall: + case ebin_ip_postinstall: + result + .with_setenv("PALUDIS_LOAD_ENVIRONMENT", stringify(params.buildroot / + stringify(params.db_entry->name.category) / ( + stringify(params.db_entry->name.package) + "-" + stringify(params.db_entry->version)) / "temp" + / "binpkgenv")) + .with_setenv("PALUDIS_SKIP_INHERIT", "yes"); + break; + + case ebin_ip_unpack: + case ebin_ip_tidyup: + case last_ebin_ip: + ; + }; + + return result; +} + +EbinInstallCommand::EbinInstallCommand(const EbinCommandParams & p, const EbinInstallCommandParams & i) : + EbinCommand(p), + install_params(i) +{ +} + +EbinMergeCommand::EbinMergeCommand(const EbinCommandParams & p, const EbinMergeCommandParams & m) : + params(p), + merge_params(m) +{ +} + +void +EbinMergeCommand::operator() () +{ + std::string tar(strip_trailing_string(stringify(merge_params.pkg_file_name), ".bz2")); + + Command build_tarball(Command("tar pcvf '" + stringify(tar) + "' ./") + .with_chdir(merge_params.image) + .with_echo_to_stderr()); + + if (0 != run_command(build_tarball)) + throw PackageInstallActionError("Error creating '" + stringify(tar) + "'"); + + Command create_env(Command("cp -f '" + stringify(merge_params.environment_file) + "' '.paludis-binpkg-environment'") + .with_chdir(merge_params.image) + .with_echo_to_stderr()); + + Command add_env_to_tarball(Command("tar rpf '" + stringify(tar) + + "' '.paludis-binpkg-environment'") + .with_chdir(merge_params.image) + .with_echo_to_stderr()); + + if (0 != run_command(create_env) || 0 != run_command(add_env_to_tarball)) + throw PackageInstallActionError("Error adding environment to '" + tar + "'"); + + Command clean_env(Command("rm -f '.paludis-binpkg-environment'") + .with_chdir(merge_params.image) + .with_echo_to_stderr()); + run_command(clean_env); + + Command compress_tarball(Command("bzip2 '" + tar + "'") + .with_chdir(merge_params.image) + .with_echo_to_stderr()); + + if (0 != run_command(compress_tarball)) + throw PackageInstallActionError("Error compressing '" + tar + "'"); +} + diff --git a/paludis/repositories/gentoo/ebin.hh b/paludis/repositories/gentoo/ebin.hh new file mode 100644 index 000000000..a471cf8a2 --- /dev/null +++ b/paludis/repositories/gentoo/ebin.hh @@ -0,0 +1,117 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_PALUDIS_REPOSITORIES_GENTOO_EBIN_HH +#define PALUDIS_GUARD_PALUDIS_PALUDIS_REPOSITORIES_GENTOO_EBIN_HH 1 + +#include <paludis/util/instantiation_policy.hh> +#include <paludis/util/fs_entry.hh> +#include <paludis/util/attributes.hh> +#include <paludis/util/collection.hh> +#include <paludis/package_database.hh> +#include <string> + +namespace paludis +{ + class Command; + +#include <paludis/repositories/gentoo/ebin-se.hh> +#include <paludis/repositories/gentoo/ebin-sr.hh> + + class EbinVersionMetadata : + public VersionMetadata, + public VersionMetadataEbuildInterface, + public VersionMetadataEbinInterface, + public VersionMetadataDepsInterface, + public VersionMetadataLicenseInterface, + public VersionMetadataOriginsInterface + { + public: + EbinVersionMetadata(const SlotName &); + virtual ~EbinVersionMetadata(); + }; + + class EbinCommand : + private InstantiationPolicy<EbinCommand, instantiation_method::NonCopyableTag> + { + protected: + EbinCommandParams params; + + EbinCommand(const EbinCommandParams &); + + virtual std::string commands() const = 0; + virtual bool success(); + virtual bool use_sandbox() const; + virtual bool failure() = 0; + virtual bool do_run_command(const Command &); + virtual Command extend_command(const Command &) = 0; + + public: + virtual ~EbinCommand(); + + virtual bool operator() (); + }; + + class EbinFetchCommand : + public EbinCommand + { + protected: + const EbinFetchCommandParams fetch_params; + + virtual std::string commands() const; + + virtual bool failure() PALUDIS_ATTRIBUTE((noreturn)); + + virtual Command extend_command(const Command &); + + public: + EbinFetchCommand(const EbinCommandParams &, const EbinFetchCommandParams &); + }; + + class EbinInstallCommand : + public EbinCommand + { + protected: + const EbinInstallCommandParams install_params; + + virtual std::string commands() const; + + virtual bool failure() PALUDIS_ATTRIBUTE((noreturn)); + + virtual Command extend_command(const Command &); + + public: + EbinInstallCommand(const EbinCommandParams &, const EbinInstallCommandParams &); + }; + + class EbinMergeCommand + { + protected: + const EbinCommandParams params; + const EbinMergeCommandParams merge_params; + + public: + EbinMergeCommand(const EbinCommandParams &, const EbinMergeCommandParams &); + + void operator() (); + }; +} + +#endif + diff --git a/paludis/repositories/gentoo/ebin.se b/paludis/repositories/gentoo/ebin.se new file mode 100644 index 000000000..cd5f8b2f0 --- /dev/null +++ b/paludis/repositories/gentoo/ebin.se @@ -0,0 +1,22 @@ +#!/bin/bash +# vim: set sw=4 sts=4 et ft=sh : + +make_enum_EbinInstallCommandPhase() +{ + prefix ebin_ip + + key ebin_ip_unpack "Initialise and unpack." + key ebin_ip_preinstall "Preinstall to a live system." + key ebin_ip_postinstall "Postinstall to a live system." + key ebin_ip_tidyup "Tidy up work." + + doxygen_comment << "END" + /** + * Which phase of an EbinInstallCommand to run. + * + * \see EbinInstallCommand + * \ingroup grpportagerepository + */ +END +} + diff --git a/paludis/repositories/gentoo/ebin.sr b/paludis/repositories/gentoo/ebin.sr new file mode 100644 index 000000000..a1bb6a2ed --- /dev/null +++ b/paludis/repositories/gentoo/ebin.sr @@ -0,0 +1,88 @@ +#!/bin/bash +# vim: set sw=4 sts=4 et : + +make_class_EbinCommandParams() +{ + key environment "const Environment *" + key db_entry "const PackageDatabaseEntry *" + key portdir FSEntry + key pkgdir FSEntry + key buildroot FSEntry + + doxygen_comment << "END" + /** + * Parameters for an EbinCommand. + * + * \see EbinCommand + * \ingroup grpebuildinterface + * \nosubgrouping + */ +END + + allow_named_args +} + +make_class_EbinFetchCommandParams() +{ + key b std::string + key flat_bin_uri std::string + key root std::string + key safe_resume bool + + doxygen_comment << "END" + /** + * Parameters for an EbinFetchCommand. + * + * \see EbinFetchCommand + * \ingroup grpebuildinterface + * \nosubgrouping + */ +END + + allow_named_args +} + +make_class_EbinInstallCommandParams() +{ + key b std::string + key root std::string + key disable_cfgpro bool + key debug_build InstallDebugOption + key slot SlotName + key phase EbinInstallCommandPhase + key config_protect std::string + key config_protect_mask std::string + key loadsaveenv_dir FSEntry + + doxygen_comment << "END" + /** + * Parameters for an EbinInstallCommand. + * + * \see EbinInstallCommand + * \ingroup grpebuildinterface + * \nosubgrouping + */ +END + + allow_named_args +} + +make_class_EbinMergeCommandParams() +{ + key image FSEntry + key environment_file FSEntry + key pkg_file_name FSEntry + + doxygen_comment << "END" + /** + * Parameters for an EbinMergeCommand. + * + * \see EbinMergeCommand + * \ingroup grpebuildinterface + * \nosubgrouping + */ +END + + allow_named_args +} + diff --git a/paludis/repositories/gentoo/ebin_entries.cc b/paludis/repositories/gentoo/ebin_entries.cc new file mode 100644 index 000000000..9ad59c467 --- /dev/null +++ b/paludis/repositories/gentoo/ebin_entries.cc @@ -0,0 +1,368 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * 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 "ebin_entries.hh" +#include <paludis/repositories/gentoo/ebin.hh> +#include <paludis/repositories/gentoo/portage_repository.hh> +#include <paludis/config_file.hh> +#include <paludis/portage_dep_parser.hh> +#include <paludis/dep_atom_flattener.hh> +#include <paludis/environment.hh> +#include <paludis/util/strip.hh> +#include <set> +#include <fstream> + +using namespace paludis; + +namespace paludis +{ + template<> + struct Implementation<EbinEntries> + { + const Environment * const environment; + PortageRepository * const portage_repository; + const PortageRepositoryParams params; + + Implementation(const Environment * const e, PortageRepository * const p, + const PortageRepositoryParams & k) : + environment(e), + portage_repository(p), + params(k) + { + } + }; +} + +EbinEntries::EbinEntries( + const Environment * const e, PortageRepository * const p, const PortageRepositoryParams & k) : + PortageRepositoryEntries(".ebin"), + PrivateImplementationPattern<EbinEntries>(new Implementation<EbinEntries>(e, p, k)) +{ +} + +EbinEntries::~EbinEntries() +{ +} + +std::tr1::shared_ptr<VersionMetadata> +EbinEntries::generate_version_metadata(const QualifiedPackageName & q, + const VersionSpec & v) const +{ + Context context("When generating version metadata for '" + stringify(q) + "-" + stringify(v) + "':"); + + std::tr1::shared_ptr<EbinVersionMetadata> result(new EbinVersionMetadata(SlotName("unset"))); + + KeyValueConfigFile f(_imp->params.location / stringify(q.category) / + stringify(q.package) / (stringify(q.package) + "-" + stringify(v) + ".ebin")); + + result->run_depend_string = f.get("RDEPEND"); + result->post_depend_string = f.get("PDEPEND"); + result->suggested_depend_string = f.get("SDEPEND"); + + result->license_string = f.get("LICENSE"); + + result->source.reset(); + result->binary.reset(); + + result->slot = SlotName(f.get("SLOT")); + result->homepage = f.get("HOMEPAGE"); + result->description = f.get("DESCRIPTION"); + result->eapi = f.get("EAPI"); + + result->provide_string = f.get("PROVIDE"); + result->src_uri = f.get("SRC_URI"); + result->restrict_string = f.get("RESTRICT"); + result->keywords = f.get("KEYWORDS"); + result->iuse = f.get("IUSE"); + result->inherited = f.get("INHERITED"); + + result->bin_uri = f.get("BIN_URI"); + + return result; +} + +void +EbinEntries::install(const QualifiedPackageName & q, const VersionSpec & v, + const InstallOptions & o, std::tr1::shared_ptr<const PortageRepositoryProfile>) const +{ + if (! _imp->portage_repository->has_version(q, v)) + throw PackageInstallActionError("Can't install '" + stringify(q) + "-" + + stringify(v) + "' since has_version failed"); + + std::tr1::shared_ptr<const VersionMetadata> metadata(_imp->portage_repository->version_metadata(q, v)); + PackageDatabaseEntry e(q, v, _imp->portage_repository->name()); + + std::string binaries, flat_bin_uri; + { + std::set<std::string> already_in_binaries; + + /* make B and FLAT_BIN_URI */ + std::tr1::shared_ptr<const DepAtom> b_atom(PortageDepParser::parse(metadata->ebin_interface->bin_uri, + PortageDepParserPolicy<PlainTextDepAtom, false>::get_instance())); + DepAtomFlattener f(_imp->params.environment, &e, b_atom); + + for (DepAtomFlattener::Iterator ff(f.begin()), ff_end(f.end()) ; ff != ff_end ; ++ff) + { + std::string::size_type pos((*ff)->text().rfind('/')); + if (std::string::npos == pos) + { + if (already_in_binaries.end() == already_in_binaries.find((*ff)->text())) + { + binaries.append((*ff)->text()); + already_in_binaries.insert((*ff)->text()); + } + } + else + { + if (already_in_binaries.end() == already_in_binaries.find((*ff)->text().substr(pos + 1))) + { + binaries.append((*ff)->text().substr(pos + 1)); + already_in_binaries.insert((*ff)->text().substr(pos + 1)); + } + } + binaries.append(" "); + + /* add * mirror entries */ + for (Environment::MirrorIterator + m(_imp->params.environment->begin_mirrors("*")), + m_end(_imp->params.environment->end_mirrors("*")) ; + m != m_end ; ++m) + flat_bin_uri.append(m->second + "/" + (*ff)->text().substr(pos + 1) + " "); + + if (0 == (*ff)->text().compare(0, 9, "mirror://")) + { + std::string mirror((*ff)->text().substr(9)); + std::string::size_type spos(mirror.find('/')); + + if (std::string::npos == spos) + throw PackageInstallActionError("Can't install '" + stringify(q) + "-" + + stringify(v) + "' since BIN_URI is broken"); + + if (! _imp->portage_repository->is_mirror(mirror.substr(0, spos)) && + _imp->params.environment->begin_mirrors(mirror.substr(0, spos)) == + _imp->params.environment->end_mirrors(mirror.substr(0, spos))) + throw PackageInstallActionError("Can't install '" + stringify(q) + "-" + + stringify(v) + "' since BIN_URI references unknown mirror:// '" + + mirror.substr(0, spos) + "'"); + + for (Environment::MirrorIterator + m(_imp->params.environment->begin_mirrors(mirror.substr(0, spos))), + m_end(_imp->params.environment->end_mirrors(mirror.substr(0, spos))) ; + m != m_end ; ++m) + flat_bin_uri.append(m->second + "/" + mirror.substr(spos + 1) + " "); + + for (RepositoryMirrorsInterface::MirrorsIterator + m(_imp->portage_repository->begin_mirrors(mirror.substr(0, spos))), + m_end(_imp->portage_repository->end_mirrors(mirror.substr(0, spos))) ; + m != m_end ; ++m) + flat_bin_uri.append(m->second + "/" + mirror.substr(spos + 1) + " "); + } + else + flat_bin_uri.append((*ff)->text()); + flat_bin_uri.append(" "); + + /* add mirror://gentoo/ entries */ + std::string master_mirror(strip_trailing_string(stringify(_imp->portage_repository->name()), "x-")); + if (_imp->portage_repository->is_mirror(master_mirror)) + { + for (Environment::MirrorIterator + m(_imp->params.environment->begin_mirrors(master_mirror)), + m_end(_imp->params.environment->end_mirrors(master_mirror)) ; + m != m_end ; ++m) + flat_bin_uri.append(m->second + "/" + (*ff)->text().substr(pos + 1) + " "); + + for (RepositoryMirrorsInterface::MirrorsIterator + m(_imp->portage_repository->begin_mirrors(master_mirror)), + m_end(_imp->portage_repository->end_mirrors(master_mirror)) ; + m != m_end ; ++m) + flat_bin_uri.append(m->second + "/" + (*ff)->text().substr(pos + 1) + " "); + } + } + } + + EbinCommandParams command_params(EbinCommandParams::create() + .environment(_imp->params.environment) + .db_entry(&e) + .portdir(_imp->params.master_repository ? _imp->params.master_repository->params().location : + _imp->params.location) + .pkgdir(_imp->params.pkgdir) + .buildroot(_imp->params.buildroot)); + + EbinFetchCommand fetch_cmd(command_params, + EbinFetchCommandParams::create() + .b(binaries) + .flat_bin_uri(flat_bin_uri) + .root(o.destination && o.destination->installed_interface ? + stringify(o.destination->installed_interface->root()) : "/") + .safe_resume(o.safe_resume)); + + fetch_cmd(); + + if (o.fetch_only) + return; + + if (! o.destination) + throw PackageInstallActionError("Can't install '" + stringify(q) + "-" + + stringify(v) + "' because no destination was provided"); + + if (! o.destination->destination_interface) + throw PackageInstallActionError("Can't install '" + stringify(q) + "-" + + stringify(v) + "' to destination '" + stringify(o.destination->name()) + + "' because destination does not provide destination_interface"); + + EbinInstallCommandParams install_params( + EbinInstallCommandParams::create() + .b(binaries) + .root(o.destination && o.destination->installed_interface ? + stringify(o.destination->installed_interface->root()) : "/") + .debug_build(o.debug_build) + .phase(ebin_ip_unpack) + .disable_cfgpro(o.no_config_protect) + .config_protect(_imp->portage_repository->profile_variable("CONFIG_PROTECT")) + .config_protect_mask(_imp->portage_repository->profile_variable("CONFIG_PROTECT_MASK")) + .loadsaveenv_dir(_imp->params.buildroot / stringify(q.category) / ( + stringify(q.package) + "-" + stringify(v)) / "temp") + .slot(SlotName(metadata->slot))); + + EbinInstallCommand build_cmd(command_params, install_params); + build_cmd(); + + if (o.destination->destination_interface->want_pre_post_phases()) + { + install_params.phase = ebin_ip_preinstall; + EbinInstallCommand preinst_cmd(command_params, install_params); + preinst_cmd(); + } + + o.destination->destination_interface->merge( + MergeOptions::create() + .package(PackageDatabaseEntry(q, v, _imp->portage_repository->name())) + .image_dir(command_params.buildroot / stringify(q.category) / (stringify(q.package) + "-" + + stringify(v)) / "image") + .environment_file(command_params.buildroot / stringify(q.category) / (stringify(q.package) + "-" + + stringify(v)) / "temp" / "loadsaveenv") + ); + + if (o.destination->destination_interface->want_pre_post_phases()) + { + install_params.phase = ebin_ip_postinstall; + EbinInstallCommand postinst_cmd(command_params, install_params); + postinst_cmd(); + } + + install_params.phase = ebin_ip_tidyup; + EbinInstallCommand tidyup_cmd(command_params, install_params); + tidyup_cmd(); +} + +std::tr1::shared_ptr<PortageRepositoryEntries> +EbinEntries::make_ebin_entries( + const Environment * const e, PortageRepository * const r, const PortageRepositoryParams & p) +{ + return std::tr1::shared_ptr<PortageRepositoryEntries>(new EbinEntries(e, r, p)); +} + +std::string +EbinEntries::get_environment_variable(const QualifiedPackageName & q, + const VersionSpec & v, const std::string & var, std::tr1::shared_ptr<const PortageRepositoryProfile>) const +{ + PackageDatabaseEntry for_package(q, v, _imp->portage_repository->name()); + + throw EnvironmentVariableActionError("Couldn't get environment variable '" + + stringify(var) + "' for package '" + stringify(for_package) + "'"); +} + +void +EbinEntries::merge(const MergeOptions & m) +{ + Context context("When merging '" + stringify(m.package) + "' at '" + stringify(m.image_dir) + + "' to ebin repository '" + stringify(_imp->portage_repository->name()) + "':"); + + if (! _imp->portage_repository->destination_interface->is_suitable_destination_for(m.package)) + throw PackageInstallActionError("Not a suitable destination for '" + stringify(m.package) + "'"); + + FSEntry ebin_dir(_imp->params.location); + ebin_dir /= stringify(m.package.name.category); + ebin_dir.mkdir(); + ebin_dir /= stringify(m.package.name.package); + ebin_dir.mkdir(); + + FSEntry ebin_file_name(ebin_dir / (stringify(m.package.name.package) + "-" + stringify(m.package.version) + ".ebin")); + std::ofstream ebin_file(stringify(ebin_file_name).c_str()); + if (! ebin_file) + throw PackageInstallActionError("Cannot write to '" + stringify(ebin_file_name) + "'"); + + std::tr1::shared_ptr<const VersionMetadata> metadata( + _imp->params.environment->package_database()->fetch_repository(m.package.repository)-> + version_metadata(m.package.name, m.package.version)); + + if (metadata->deps_interface) + { + ebin_file << "RDEPEND=" << metadata->deps_interface->run_depend_string << std::endl; + ebin_file << "PDEPEND=" << metadata->deps_interface->post_depend_string << std::endl; + ebin_file << "SDEPEND=" << metadata->deps_interface->suggested_depend_string << std::endl; + } + + if (metadata->license_interface) + ebin_file << "LICENSE=" << metadata->license_interface->license_string << std::endl; + + ebin_file << "SLOT=" << metadata->slot << std::endl; + ebin_file << "HOMEPAGE=" << metadata->homepage << std::endl; + ebin_file << "DESCRIPTION=" << metadata->description << std::endl; + ebin_file << "EAPI=" << metadata->eapi << std::endl; + + if (metadata->ebuild_interface) + { + ebin_file << "PROVIDE=" << metadata->ebuild_interface->provide_string << std::endl; + ebin_file << "SRC_URI=" << metadata->ebuild_interface->src_uri << std::endl; + ebin_file << "RESTRICT=" << metadata->ebuild_interface->restrict_string << std::endl; + ebin_file << "KEYWORDS=" << metadata->ebuild_interface->keywords << std::endl; + ebin_file << "IUSE=" << metadata->ebuild_interface->iuse << std::endl; + ebin_file << "INHERITED=" << metadata->ebuild_interface->inherited << std::endl; + } + + FSEntry pkg_file_name(_imp->params.pkgdir / ( + stringify(_imp->portage_repository->name()) + "--" + + stringify(m.package.name.category) + "--" + + stringify(m.package.name.package) + "-" + + stringify(m.package.version) + ".tar.bz2")); + + ebin_file << "BIN_URI=" << pkg_file_name.basename() << std::endl; + + if (pkg_file_name.exists()) + pkg_file_name.unlink(); + + EbinCommandParams command_params(EbinCommandParams::create() + .environment(_imp->params.environment) + .db_entry(&m.package) + .portdir(_imp->params.master_repository ? _imp->params.master_repository->params().location : + _imp->params.location) + .pkgdir(_imp->params.pkgdir) + .buildroot(_imp->params.buildroot)); + + EbinMergeCommand merge_cmd( + command_params, + EbinMergeCommandParams::create() + .pkg_file_name(pkg_file_name) + .image(m.image_dir) + .environment_file(m.environment_file)); + + merge_cmd(); +} + diff --git a/paludis/repositories/gentoo/ebin_entries.hh b/paludis/repositories/gentoo/ebin_entries.hh new file mode 100644 index 000000000..1679b7849 --- /dev/null +++ b/paludis/repositories/gentoo/ebin_entries.hh @@ -0,0 +1,67 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_GENTOO_EBIN_ENTRIES_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_GENTOO_EBIN_ENTRIES_HH 1 + +#include <paludis/repositories/gentoo/portage_repository_entries.hh> +#include <paludis/repositories/gentoo/portage_repository_params.hh> +#include <paludis/util/private_implementation_pattern.hh> + +namespace paludis +{ + class FSEntry; + class PortageRepository; + + /** + * PortageRepositoryEntries handler for ebins. + * + * \ingroup grpportagerepository + */ + class PALUDIS_VISIBLE EbinEntries : + public PortageRepositoryEntries, + private PrivateImplementationPattern<EbinEntries> + { + public: + static std::tr1::shared_ptr<PortageRepositoryEntries> + make_ebin_entries(const Environment * const, + PortageRepository * const, const PortageRepositoryParams &); + + EbinEntries(const Environment * const, + PortageRepository * const portage_repository, + const PortageRepositoryParams &); + + virtual ~EbinEntries(); + + virtual std::tr1::shared_ptr<VersionMetadata> generate_version_metadata(const QualifiedPackageName &, + const VersionSpec &) const; + + virtual std::string get_environment_variable(const QualifiedPackageName &, + const VersionSpec &, const std::string & var, + std::tr1::shared_ptr<const PortageRepositoryProfile>) const; + + virtual void install(const QualifiedPackageName &, const VersionSpec &, + const InstallOptions &, std::tr1::shared_ptr<const PortageRepositoryProfile>) const; + + virtual void merge(const MergeOptions &); + }; +} + + +#endif diff --git a/paludis/repositories/gentoo/ebuild.cc b/paludis/repositories/gentoo/ebuild.cc index dc7d23e3d..cab971ba8 100644 --- a/paludis/repositories/gentoo/ebuild.cc +++ b/paludis/repositories/gentoo/ebuild.cc @@ -305,19 +305,19 @@ EbuildInstallCommand::commands() const { switch (install_params.phase) { - case ip_build: + case ebuild_ip_build: return "init setup unpack compile test install saveenv"; - case ip_preinstall: + case ebuild_ip_preinstall: return "loadenv strip preinst saveenv"; - case ip_postinstall: + case ebuild_ip_postinstall: return "loadenv postinst saveenv"; - case ip_tidyup: + case ebuild_ip_tidyup: return "tidyup"; - case last_ip: + case last_ebuild_ip: ; }; @@ -447,6 +447,7 @@ EbuildVersionMetadata::EbuildVersionMetadata() : .license_interface(this) .virtual_interface(0) .origins_interface(0) + .ebin_interface(0) ), VersionMetadataEbuildInterface(), VersionMetadataDepsInterface(PortageDepParser::parse_depend), diff --git a/paludis/repositories/gentoo/ebuild.se b/paludis/repositories/gentoo/ebuild.se index 7ef0aa933..05e9464b8 100644 --- a/paludis/repositories/gentoo/ebuild.se +++ b/paludis/repositories/gentoo/ebuild.se @@ -3,12 +3,12 @@ make_enum_EbuildInstallCommandPhase() { - prefix ip + prefix ebuild_ip - key ip_build "Build the package." - key ip_preinstall "Preinstall to a live system." - key ip_postinstall "Postinstall to a live system." - key ip_tidyup "Tidy up work." + key ebuild_ip_build "Build the package." + key ebuild_ip_preinstall "Preinstall to a live system." + key ebuild_ip_postinstall "Postinstall to a live system." + key ebuild_ip_tidyup "Tidy up work." doxygen_comment << "END" /** diff --git a/paludis/repositories/gentoo/ebuild/Makefile.am b/paludis/repositories/gentoo/ebuild/Makefile.am index 4b1842d46..a1fe31c52 100644 --- a/paludis/repositories/gentoo/ebuild/Makefile.am +++ b/paludis/repositories/gentoo/ebuild/Makefile.am @@ -9,7 +9,9 @@ libexecprogdir = $(libexecdir)/paludis/ libexecprog_SCRIPTS = \ build_functions.bash \ builtin_fetch.bash \ + builtin_fetchbin.bash \ builtin_init.bash \ + builtin_initbin.bash \ builtin_loadenv.bash \ builtin_merge.bash \ builtin_metadata.bash \ @@ -17,6 +19,7 @@ libexecprog_SCRIPTS = \ builtin_strip.bash \ builtin_tidyup.bash \ builtin_unmerge.bash \ + builtin_unpackbin.bash \ builtin_variable.bash \ die_functions.bash \ ebuild.bash \ diff --git a/paludis/repositories/gentoo/ebuild/builtin_fetchbin.bash b/paludis/repositories/gentoo/ebuild/builtin_fetchbin.bash new file mode 100644 index 000000000..90242b151 --- /dev/null +++ b/paludis/repositories/gentoo/ebuild/builtin_fetchbin.bash @@ -0,0 +1,98 @@ +#!/bin/bash +# vim: set sw=4 sts=4 et : + +# Copyright (c) 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org> +# +# This file is part of the Paludis package manager. Paludis is free software; +# you can redistribute it and/or modify it under the terms of the GNU General +# 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 + +builtin_fetchbin() +{ + [[ -d "${PKGDIR}" ]] || die "PKGDIR \"${PKGDIR}\" is not a directory" + + local a nofetch unique_aa old_aa + for a in ${FLAT_BIN_URI} ; do + local aa=${a##*/} + hasq "${aa}" ${unique_aa} || unique_aa="${unique_aa} ${aa}" + + if [[ -f "${PKGDIR}/${aa}" ]] && [[ "0" != $(getfsize "${PKGDIR}/${aa}") ]] ; then + if [[ "${old_aa}" != "${aa}" ]] ; then + ebuild_section "Already have ${aa}" + old_aa="${aa}" + fi + else + if [[ -f "${PKGDIR}/${aa}" ]] ; then + ebuild_section "Trying to remove existing ${aa}..." + rm -f "${PKGDIR}/${aa}" + fi + + if ! hasq fetchbin ${RESTRICT} ; then + if [[ "${old_aa}" != "${aa}" ]] ; then + ebuild_section "Need to fetch ${aa}" + old_aa="${aa}" + fi + local d + for d in ${PALUDIS_FETCHERS_DIRS:-${PALUDIS_EBUILD_DIR}/fetchers/} ; do + prg=${d}/do$(echo ${a%%://*} | tr '[:upper:]' '[:lower:]' ) + ebuild_notice "debug" "fetcher program candidate for '${a}' is '${prg}'" + [[ -x "${prg}" ]] && break + done + if [[ -x "${prg}" ]] ; then + ${prg} "${a}" "${PKGDIR}/${aa}" + else + eerror "Don't know how to fetch '${a}'" + fi + else + if ! [[ "${old_aa}" != "${aa}" ]] ; then + ebuild_section "Can't fetch ${aa}" + old_aa="${aa}" + fi + fi + fi + done + + for a in ${unique_aa} ; do + [[ -f ${PKGDIR}/${a} ]] || nofetch="${nofetch} ${a}" + done + + if [[ -n "${nofetch}" ]] ; then + local c + echo + eerror "Couldn't fetch the following components:" + for c in ${nofetch} ; do + eerror " * ${c}" + done + echo + die "builtin_fetchbin failed" + fi +} + +ebuild_f_fetchbin() +{ + local old_sandbox_write="${SANDBOX_WRITE}" + [[ -z "${PALUDIS_DO_NOTHING_SANDBOXY}" ]] && SANDBOX_WRITE="${SANDBOX_WRITE+${SANDBOX_WRITE}:}${PKGDIR}" + if hasq "fetchbin" ${RESTRICT} ; then + ebuild_section "Skipping builtin_fetchbin (RESTRICT)" + elif hasq "fetchbin" ${SKIP_FUNCTIONS} ; then + ebuild_section "Skipping builtin_fetchbin (SKIP_FUNCTIONS)" + else + ebuild_section "Starting builtin_fetchbin" + builtin_fetchbin + ebuild_section "Done builtin_fetchbin" + fi + [[ -z "${PALUDIS_DO_NOTHING_SANDBOXY}" ]] && SANDBOX_WRITE="${old_sandbox_write}" + true +} + + + diff --git a/paludis/repositories/gentoo/ebuild/builtin_initbin.bash b/paludis/repositories/gentoo/ebuild/builtin_initbin.bash new file mode 100644 index 000000000..e3fb370a6 --- /dev/null +++ b/paludis/repositories/gentoo/ebuild/builtin_initbin.bash @@ -0,0 +1,75 @@ +#!/bin/bash +# vim: set sw=4 sts=4 et : + +# Copyright (c) 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org> +# +# This file is part of the Paludis package manager. Paludis is free software; +# you can redistribute it and/or modify it under the terms of the GNU General +# 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 + +builtin_initbin() +{ + export ROOT="${ROOT//+(\/)//}" + + local a + for a in P PV PR PN PVR PF CATEGORY PORTDIR \ + PKGDIR KV PALUDIS_TMPDIR PALUDIS_EBUILD_LOG_LEVEL PALUDIS_EBUILD_DIR \ + CHOST PALUDIS_COMMAND ROOT ; do + [[ -z "${!a}" ]] && die "\$${a} unset or empty" + declare -r ${a}="${!a}" + done + + for a in PKGDIR ; do + [[ -d "${!a}" ]] || die "\$${a} (\"${!a}\") not a directory" + done + + if [[ -e "${PALUDIS_TMPDIR}/${CATEGORY}/${PF}" ]] ; then + if type -p chflags &>/dev/null; then + chflags -R 0 "${PALUDIS_TMPDIR}/${CATEGORY}/${PF}" || die "Couldn't remove flags from workdir" + fi + rm -fr "${PALUDIS_TMPDIR}/${CATEGORY}/${PF}" || die "Couldn't remove previous work" + fi + + export WORKDIR="${PALUDIS_TMPDIR}/${CATEGORY}/${PF}/work" + mkdir -p "${WORKDIR}" || die "Couldn't create \$WORKDIR (\"${WORKDIR}\")" + declare -r WORKDIR="${WORKDIR}" + + export T="${PALUDIS_TMPDIR}/${CATEGORY}/${PF}/temp/" + mkdir -p "${T}" || die "Couldn't create \$T (\"${T}\")" + declare -r T="${T}" + export HOME="${T}" + + export D="${PALUDIS_TMPDIR}/${CATEGORY}/${PF}/image/" + export D="${D//+(\/)//}" + mkdir -p "${D}" || die "Couldn't create \$D (\"${D}\")" + declare -r D="${D}" + + export IMAGE="${D}" + declare -r IMAGE="${IMAGE}" + + export S="${WORKDIR}/${P}" +} + +ebuild_f_initbin() +{ + if hasq "initbin" ${RESTRICT} ; then + ebuild_section "Skipping builtin_initbin (RESTRICT)" + elif hasq "init" ${SKIP_FUNCTIONS} ; then + ebuild_section "Skipping builtin_initbin (SKIP_FUNCTIONS)" + else + ebuild_section "Starting builtin_initbin" + builtin_initbin + ebuild_section "Done builtin_initbin" + fi +} + + diff --git a/paludis/repositories/gentoo/ebuild/builtin_unpackbin.bash b/paludis/repositories/gentoo/ebuild/builtin_unpackbin.bash new file mode 100644 index 000000000..2ed7c28ba --- /dev/null +++ b/paludis/repositories/gentoo/ebuild/builtin_unpackbin.bash @@ -0,0 +1,45 @@ +#!/bin/bash +# vim: set sw=4 sts=4 et : + +# Copyright (c) 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org> +# +# This file is part of the Paludis package manager. Paludis is free software; +# you can redistribute it and/or modify it under the terms of the GNU General +# 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 + +builtin_unpackbin() +{ + [[ -n "${B}" ]] && unpack --binary ${B} + + [[ -f "${IMAGE}/.paludis-binpkg-environment" ]] || \ + die "No saved environment in binary tarball" + + mv "${IMAGE}"/.paludis-binpkg-environment ${T}/binpkgenv \ + || die "Couldn't extract saved environment" +} + +ebuild_f_unpackbin() +{ + cd ${WORKDIR} || die "cd to \${WORKDIR} (\"${WORKDIR}\") failed" + + if hasq "unpackbin" ${RESTRICT} ; then + ebuild_section "Skipping builtin_unpackbin (RESTRICT)" + elif hasq "unpackbin" ${SKIP_FUNCTIONS} ; then + ebuild_section "Skipping builtin_unpackbin (SKIP_FUNCTIONS)" + else + ebuild_section "Starting builtin_unpackbin" + builtin_unpackbin + ebuild_section "Done builtin_unpackbin" + fi +} + + diff --git a/paludis/repositories/gentoo/ebuild/ebuild.bash b/paludis/repositories/gentoo/ebuild/ebuild.bash index 4ec0c8ceb..22ffde2b6 100755 --- a/paludis/repositories/gentoo/ebuild/ebuild.bash +++ b/paludis/repositories/gentoo/ebuild/ebuild.bash @@ -57,7 +57,7 @@ export PALUDIS_EBUILD_MODULES_DIR="${EBUILD_MODULES_DIR}" ebuild_load_module() { if ! source "${EBUILD_MODULES_DIR}/${1}.bash" ; then - type die && die "Error loading module ${1}" + type die &>/dev/null && die "Error loading module ${1}" echo "Error loading module ${1}" 1>&2 exit 123 fi @@ -167,6 +167,8 @@ ebuild_scrub_environment() unset -v PALUDIS_HOME PALUDIS_PID EBUILD_KILL_PID ROOT unset -v CATEGORY PN PV P PVR PF ${!LD_*} + unset -v EBUILD E_DEPEND E_RDEPEND E_IUSE E_PDEPEND E_KEYWORDS + for v in ${!SANDBOX*}; do [[ "${v}" == SANDBOX_ACTIVE ]] || unset "${v}" done @@ -185,7 +187,7 @@ ebuild_scrub_environment() sed -i -e 's:^declare -rx:declare -x:' "${filters[@]}" "${1}" } -ebuild_load_ebuild() +ebuild_load_environment() { if [[ -n "${PALUDIS_LOAD_ENVIRONMENT}" ]] ; then [[ -d ${PALUDIS_TMPDIR} ]] \ @@ -203,8 +205,13 @@ ebuild_load_ebuild() !!! problem lies. " - bunzip2 < "${PALUDIS_LOAD_ENVIRONMENT}" > ${PALUDIS_TMPDIR}/environment-${CATEGORY}-${PF} \ - || die "Can't extract ${PALUDIS_LOAD_ENVIRONMENT}" + if [[ "${PALUDIS_LOAD_ENVIRONMENT%.bz2}" != "${PALUDIS_LOAD_ENVIRONMENT}" ]] ; then + bunzip2 < "${PALUDIS_LOAD_ENVIRONMENT}" > ${PALUDIS_TMPDIR}/environment-${CATEGORY}-${PF} \ + || die "Can't extract ${PALUDIS_LOAD_ENVIRONMENT}" + else + cp "${PALUDIS_LOAD_ENVIRONMENT}" "${PALUDIS_TMPDIR}/environment-${CATEGORY}-${PF}" \ + || die "Can't copy ${PALUDIS_LOAD_ENVIRONMENT}" + fi ebuild_scrub_environment "${PALUDIS_TMPDIR}/environment-${CATEGORY}-${PF}" \ || die "Can't load saved environment for cleaning" @@ -217,20 +224,16 @@ ebuild_load_ebuild() rm "${PALUDIS_TMPDIR}/environment-${CATEGORY}-${PF}" fi +} +ebuild_load_ebuild() +{ export EBUILD="${1}" unset IUSE DEPEND RDEPEND PDEPEND KEYWORDS - if [[ "${CATEGORY}" == "virtual" ]] ; then - if [[ -f "${1}" ]] ; then - source ${1} || die "Error sourcing ebuild '${1}'" - elif [[ -e "${1}" ]] ; then - die "'${1}' exists but is not a regular file" - fi - else - [[ -f "${1}" ]] || die "Ebuild '${1}' is not a file" - source ${1} || die "Error sourcing ebuild '${1}'" - fi + [[ -f "${1}" ]] || die "Ebuild '${1}' is not a file" + source ${1} || die "Error sourcing ebuild '${1}'" + [[ ${RDEPEND-unset} == "unset" ]] && RDEPEND="${DEPEND}" IUSE="${IUSE} ${E_IUSE}" @@ -286,7 +289,7 @@ ebuild_main() for action in $@ ; do case ${action} in - metadata|variable|init|fetch|merge|unmerge|tidyup|strip|loadenv|saveenv) + metadata|variable|init|fetch|merge|unmerge|tidyup|strip|loadenv|saveenv|fetchbin|initbin|unpackbin) ebuild_load_module builtin_${action} ;; @@ -321,7 +324,10 @@ ebuild_main() fi perform_hook ebuild_${action}_post else - ebuild_load_ebuild "${ebuild}" + ebuild_load_environment + if [[ "${ebuild}" != "-" ]] ; then + ebuild_load_ebuild "${ebuild}" + fi for action in $@ ; do export EBUILD_PHASE="${action}" perform_hook ebuild_${action}_pre @@ -343,5 +349,5 @@ ebuild_main() fi } -ebuild_main $@ +ebuild_main "$@" diff --git a/paludis/repositories/gentoo/ebuild_entries.cc b/paludis/repositories/gentoo/ebuild_entries.cc index 0841cfee7..7ec8f7864 100644 --- a/paludis/repositories/gentoo/ebuild_entries.cc +++ b/paludis/repositories/gentoo/ebuild_entries.cc @@ -477,13 +477,14 @@ EbuildEntries::install(const QualifiedPackageName & q, const VersionSpec & v, EbuildInstallCommandParams install_params( EbuildInstallCommandParams::create() - .phase(ip_build) + .phase(ebuild_ip_build) .use(use) .a(archives) .aa(all_archives) .use_expand(join(p->begin_use_expand(), p->end_use_expand(), " ")) .expand_vars(expand_vars) - .root(stringify(o.destination->installed_interface->root())) + .root(o.destination && o.destination->installed_interface ? + stringify(o.destination->installed_interface->root()) : "/") .profiles(_imp->params.profiles) .disable_cfgpro(o.no_config_protect) .debug_build(o.debug_build) @@ -498,7 +499,7 @@ EbuildEntries::install(const QualifiedPackageName & q, const VersionSpec & v, if (o.destination->destination_interface->want_pre_post_phases()) { - install_params.phase = ip_preinstall; + install_params.phase = ebuild_ip_preinstall; EbuildInstallCommand preinst_cmd(command_params, install_params); preinst_cmd(); } @@ -514,12 +515,12 @@ EbuildEntries::install(const QualifiedPackageName & q, const VersionSpec & v, if (o.destination->destination_interface->want_pre_post_phases()) { - install_params.phase = ip_postinstall; + install_params.phase = ebuild_ip_postinstall; EbuildInstallCommand postinst_cmd(command_params, install_params); postinst_cmd(); } - install_params.phase = ip_tidyup; + install_params.phase = ebuild_ip_tidyup; EbuildInstallCommand tidyup_cmd(command_params, install_params); tidyup_cmd(); } @@ -560,3 +561,9 @@ EbuildEntries::make_ebuild_entries( return std::tr1::shared_ptr<PortageRepositoryEntries>(new EbuildEntries(e, r, p)); } +void +EbuildEntries::merge(const MergeOptions &) +{ + throw InternalError(PALUDIS_HERE, "Cannot merge to PortageRepository with ebuild entries"); +} + diff --git a/paludis/repositories/gentoo/ebuild_entries.hh b/paludis/repositories/gentoo/ebuild_entries.hh index 7755081d4..6e50034f1 100644 --- a/paludis/repositories/gentoo/ebuild_entries.hh +++ b/paludis/repositories/gentoo/ebuild_entries.hh @@ -64,6 +64,8 @@ namespace paludis virtual void install(const QualifiedPackageName &, const VersionSpec &, const InstallOptions &, std::tr1::shared_ptr<const PortageRepositoryProfile>) const; + + virtual void merge(const MergeOptions &) PALUDIS_ATTRIBUTE((noreturn)); }; } diff --git a/paludis/repositories/gentoo/make_ebin_repository.cc b/paludis/repositories/gentoo/make_ebin_repository.cc new file mode 100644 index 000000000..ba9bcbfd6 --- /dev/null +++ b/paludis/repositories/gentoo/make_ebin_repository.cc @@ -0,0 +1,165 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * 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 "make_ebin_repository.hh" +#include <paludis/util/log.hh> +#include <paludis/util/collection_concrete.hh> +#include <paludis/util/tokeniser.hh> +#include <paludis/repositories/gentoo/portage_repository_exceptions.hh> +#include <paludis/environment.hh> + +using namespace paludis; + +std::tr1::shared_ptr<PortageRepository> +paludis::make_ebin_repository( + Environment * const env, + std::tr1::shared_ptr<const AssociativeCollection<std::string, std::string> > m) +{ + std::string repo_file(m->end() == m->find("repo_file") ? std::string("?") : + m->find("repo_file")->second); + + Context context("When making ebin repository from repo_file '" + repo_file + "':"); + + std::string location; + if (m->end() == m->find("location") || ((location = m->find("location")->second)).empty()) + throw PortageRepositoryConfigurationError("Key 'location' not specified or empty"); + + std::tr1::shared_ptr<const RepositoryName> master_repository_name; + std::tr1::shared_ptr<const PortageRepository> master_repository; + if (m->end() != m->find("master_repository") && ! m->find("master_repository")->second.empty()) + { + Context context_local("When finding configuration information for master_repository '" + + stringify(m->find("master_repository")->second) + "':"); + + master_repository_name.reset(new RepositoryName(m->find("master_repository")->second)); + + std::tr1::shared_ptr<const Repository> master_repository_uncasted( + env->package_database()->fetch_repository(*master_repository_name)); + + if (master_repository_uncasted->format() != "ebuild" && master_repository_uncasted->format() != "ebin") + throw PortageRepositoryConfigurationError("Master repository format is '" + + stringify(master_repository_uncasted->format()) + "', not 'ebuild' or 'ebin'"); + + master_repository = std::tr1::static_pointer_cast<const PortageRepository>(master_repository_uncasted); + + if (master_repository->params().master_repository) + throw PortageRepositoryConfigurationError("Requested master repository has a master_repository of '" + + stringify(master_repository->params().master_repository->name()) + "', so it cannot " + "be used as a master repository"); + } + + std::tr1::shared_ptr<FSEntryCollection> profiles(new FSEntryCollection::Concrete); + if (m->end() != m->find("profiles")) + WhitespaceTokeniser::get_instance()->tokenise(m->find("profiles")->second, + create_inserter<FSEntry>(std::back_inserter(*profiles))); + + if (profiles->empty()) + { + if (master_repository) + std::copy(master_repository->params().profiles->begin(), + master_repository->params().profiles->end(), profiles->inserter()); + else + throw PortageRepositoryConfigurationError("No profiles have been specified"); + } + + std::tr1::shared_ptr<FSEntryCollection> eclassdirs(new FSEntryCollection::Concrete); + + std::string pkgdir; + if (m->end() == m->find("pkgdir") || ((pkgdir = m->find("pkgdir")->second)).empty()) + { + if (master_repository) + pkgdir = stringify(master_repository->params().pkgdir); + else + pkgdir = location + "/packages"; + } + if (pkgdir == "/var/empty" || pkgdir.empty()) + throw PortageRepositoryConfigurationError("Key 'pkgdir' not specified or empty"); + + std::string setsdir; + if (m->end() == m->find("setsdir") || ((setsdir = m->find("setsdir")->second)).empty()) + setsdir = location + "/sets"; + + std::string securitydir; + if (m->end() == m->find("securitydir") || ((securitydir = m->find("securitydir")->second)).empty()) + securitydir = location + "/metadata/glsa"; + + std::string newsdir; + if (m->end() == m->find("newsdir") || ((newsdir = m->find("newsdir")->second)).empty()) + newsdir = location + "/metadata/news"; + + std::string names_cache; + if (m->end() == m->find("names_cache") || ((names_cache = m->find("names_cache")->second)).empty()) + { + Log::get_instance()->message(ll_warning, lc_no_context, "The names_cache key is not set in '" + + repo_file + "'. You should read http://paludis.pioto.org/cachefiles.html and select an " + "appropriate value."); + names_cache = "/var/empty"; + } + + std::string sync; + if (m->end() != m->find("sync")) + sync = m->find("sync")->second; + + std::string sync_options; + if (m->end() != m->find("sync_options")) + sync_options = m->find("sync_options")->second; + + if (m->end() != m->find("sync_exclude")) + { + Log::get_instance()->message(ll_warning, lc_no_context, "The sync_exclude key in '" + + repo_file + "' is deprecated in favour of sync_options = --exclude-from="); + if (! sync_options.empty()) + sync_options += " "; + sync_options += "--exclude-from='" + m->find("sync_exclude")->second + "'"; + } + + std::string buildroot; + if (m->end() == m->find("buildroot") || ((buildroot = m->find("buildroot")->second)).empty()) + buildroot = "/var/tmp/paludis"; + + return std::tr1::shared_ptr<PortageRepository>(new PortageRepository(PortageRepositoryParams::create() + .entry_format("ebin") + .environment(env) + .location(location) + .profiles(profiles) + .cache(FSEntry("/var/empty")) + .write_cache(FSEntry("/var/empty")) + .names_cache(names_cache) + .eclassdirs(std::tr1::shared_ptr<const FSEntryCollection>(new FSEntryCollection::Concrete)) + .distdir(FSEntry("/var/empty")) + .pkgdir(pkgdir) + .securitydir(securitydir) + .setsdir(setsdir) + .newsdir(newsdir) + .sync(sync) + .sync_options(sync_options) + .master_repository(master_repository) + .enable_destinations(true) + .buildroot(buildroot))); +} + +std::tr1::shared_ptr<Repository> +paludis::make_ebin_repository_wrapped( + Environment * const env, + std::tr1::shared_ptr<const AssociativeCollection<std::string, std::string> > m) +{ + return make_ebin_repository(env, m); +} + + diff --git a/paludis/repositories/gentoo/make_ebin_repository.hh b/paludis/repositories/gentoo/make_ebin_repository.hh new file mode 100644 index 000000000..3fd67d1be --- /dev/null +++ b/paludis/repositories/gentoo/make_ebin_repository.hh @@ -0,0 +1,45 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_GENTOO_MAKE_EBIN_REPOSITORY_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_GENTOO_MAKE_EBIN_REPOSITORY_HH 1 + +#include <paludis/repositories/gentoo/portage_repository.hh> + +namespace paludis +{ + /** + * Create an ebin format repository. + * + * \see PortageRepository + * \ingroup grpportagerepository + */ + std::tr1::shared_ptr<PortageRepository> + make_ebin_repository( + Environment * const, + std::tr1::shared_ptr<const AssociativeCollection<std::string, std::string> >) PALUDIS_VISIBLE; + + std::tr1::shared_ptr<Repository> + make_ebin_repository_wrapped( + Environment * const env, + std::tr1::shared_ptr<const AssociativeCollection<std::string, std::string> > m); +} + + +#endif diff --git a/paludis/repositories/gentoo/make_ebuild_repository.cc b/paludis/repositories/gentoo/make_ebuild_repository.cc index 97e37d646..13d882bac 100644 --- a/paludis/repositories/gentoo/make_ebuild_repository.cc +++ b/paludis/repositories/gentoo/make_ebuild_repository.cc @@ -102,6 +102,15 @@ paludis::make_ebuild_repository( distdir = location + "/distfiles"; } + std::string pkgdir; + if (m->end() == m->find("pkgdir") || ((pkgdir = m->find("pkgdir")->second)).empty()) + { + if (master_repository) + pkgdir = stringify(master_repository->params().pkgdir); + else + pkgdir = location + "/packages"; + } + std::string setsdir; if (m->end() == m->find("setsdir") || ((setsdir = m->find("setsdir")->second)).empty()) setsdir = location + "/sets"; @@ -166,13 +175,14 @@ paludis::make_ebuild_repository( .names_cache(names_cache) .eclassdirs(eclassdirs) .distdir(distdir) - .pkgdir(FSEntry("/var/empty")) + .pkgdir(pkgdir) .securitydir(securitydir) .setsdir(setsdir) .newsdir(newsdir) .sync(sync) .sync_options(sync_options) .master_repository(master_repository) + .enable_destinations(false) .buildroot(buildroot))); } diff --git a/paludis/repositories/gentoo/portage_repository.cc b/paludis/repositories/gentoo/portage_repository.cc index 26c2962f6..824f6df10 100644 --- a/paludis/repositories/gentoo/portage_repository.cc +++ b/paludis/repositories/gentoo/portage_repository.cc @@ -290,7 +290,7 @@ PortageRepository::PortageRepository(const PortageRepositoryParams & p) : .provides_interface(0) .contents_interface(0) .config_interface(0) - .destination_interface(0) + .destination_interface(p.enable_destinations ? this : 0) .licenses_interface(this), p.entry_format), PrivateImplementationPattern<PortageRepository>(new Implementation<PortageRepository>(this, p)) @@ -1247,3 +1247,28 @@ PortageRepository::params() const return _imp->params; } +bool +PortageRepository::is_suitable_destination_for(const PackageDatabaseEntry & e) const +{ + std::string f(_imp->params.environment->package_database()->fetch_repository(e.repository)->format()); + return f == "ebuild"; +} + +bool +PortageRepository::is_default_destination() const +{ + return false; +} + +bool +PortageRepository::want_pre_post_phases() const +{ + return false; +} + +void +PortageRepository::merge(const MergeOptions & o) +{ + _imp->entries_ptr->merge(o); +} + diff --git a/paludis/repositories/gentoo/portage_repository.hh b/paludis/repositories/gentoo/portage_repository.hh index 23ff2ede5..41da83563 100644 --- a/paludis/repositories/gentoo/portage_repository.hh +++ b/paludis/repositories/gentoo/portage_repository.hh @@ -59,6 +59,7 @@ namespace paludis public RepositoryEnvironmentVariableInterface, public RepositoryMirrorsInterface, public RepositoryVirtualsInterface, + public RepositoryDestinationInterface, public RepositoryLicensesInterface, private PrivateImplementationPattern<PortageRepository> { @@ -135,6 +136,15 @@ namespace paludis /* end of RepositoryUseInterface */ + /* RepositoryDestinationInterface */ + + virtual bool is_suitable_destination_for(const PackageDatabaseEntry &) const; + virtual bool is_default_destination() const; + virtual bool want_pre_post_phases() const; + virtual void merge(const MergeOptions &); + + /* end of RepositoryDestinationInterface */ + public: virtual std::tr1::shared_ptr<const RepositoryInfo> info(bool verbose) const; diff --git a/paludis/repositories/gentoo/portage_repository_entries.cc b/paludis/repositories/gentoo/portage_repository_entries.cc index 6abed92ba..06140541f 100644 --- a/paludis/repositories/gentoo/portage_repository_entries.cc +++ b/paludis/repositories/gentoo/portage_repository_entries.cc @@ -1,7 +1,7 @@ /* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* - * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * Copyright (c) 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org> * * This file is part of the Paludis package manager. Paludis is free software; * you can redistribute it and/or modify it under the terms of the GNU General @@ -19,6 +19,7 @@ #include "portage_repository_entries.hh" #include "ebuild_entries.hh" +#include "ebin_entries.hh" using namespace paludis; @@ -39,5 +40,6 @@ NoSuchPortageRepositoryEntriesType::NoSuchPortageRepositoryEntriesType(const std PortageRepositoryEntriesMaker::PortageRepositoryEntriesMaker() { register_maker("ebuild", &EbuildEntries::make_ebuild_entries); + register_maker("ebin", &EbinEntries::make_ebin_entries); } diff --git a/paludis/repositories/gentoo/portage_repository_entries.hh b/paludis/repositories/gentoo/portage_repository_entries.hh index bb85424d1..d9cf0da68 100644 --- a/paludis/repositories/gentoo/portage_repository_entries.hh +++ b/paludis/repositories/gentoo/portage_repository_entries.hh @@ -92,6 +92,8 @@ namespace paludis virtual void install(const QualifiedPackageName &, const VersionSpec &, const InstallOptions &, std::tr1::shared_ptr<const PortageRepositoryProfile>) const = 0; + + virtual void merge(const MergeOptions &) = 0; }; /** diff --git a/paludis/repositories/gentoo/portage_repository_params.sr b/paludis/repositories/gentoo/portage_repository_params.sr index e741dc6ca..09b94959e 100644 --- a/paludis/repositories/gentoo/portage_repository_params.sr +++ b/paludis/repositories/gentoo/portage_repository_params.sr @@ -20,6 +20,7 @@ make_class_PortageRepositoryParams() key sync_options std::string key buildroot FSEntry key master_repository "std::tr1::shared_ptr<const PortageRepository>" + key enable_destinations bool doxygen_comment << "END" /** diff --git a/paludis/repositories/gentoo/portage_virtual_version_metadata.cc b/paludis/repositories/gentoo/portage_virtual_version_metadata.cc index a10d4bc99..1532066ce 100644 --- a/paludis/repositories/gentoo/portage_virtual_version_metadata.cc +++ b/paludis/repositories/gentoo/portage_virtual_version_metadata.cc @@ -33,6 +33,7 @@ PortageVirtualVersionMetadata::PortageVirtualVersionMetadata(const SlotName & s, .license_interface(0) .cran_interface(0) .origins_interface(0) + .ebin_interface(0) ), VersionMetadataVirtualInterface(e), VersionMetadataDepsInterface(&PortageDepParser::parse_depend) diff --git a/paludis/repositories/gentoo/registration.cc b/paludis/repositories/gentoo/registration.cc index 9904b2cbc..5bb5599c8 100644 --- a/paludis/repositories/gentoo/registration.cc +++ b/paludis/repositories/gentoo/registration.cc @@ -19,6 +19,7 @@ #include <paludis/repositories/repository_maker.hh> #include <paludis/repositories/gentoo/make_ebuild_repository.hh> +#include <paludis/repositories/gentoo/make_ebin_repository.hh> #include <paludis/repositories/gentoo/vdb_repository.hh> #include <paludis/util/log.hh> #include "config.h" @@ -55,6 +56,7 @@ namespace void register_repositories(RepositoryMaker * maker) { maker->register_maker("ebuild", &make_ebuild_repository_wrapped); + maker->register_maker("ebin", &make_ebin_repository_wrapped); maker->register_maker("portage", &make_portage_repository); maker->register_maker("vdb", &VDBRepository::make_vdb_repository); } diff --git a/paludis/repositories/gentoo/vdb_repository.cc b/paludis/repositories/gentoo/vdb_repository.cc index 0758b022f..108f6dead 100644 --- a/paludis/repositories/gentoo/vdb_repository.cc +++ b/paludis/repositories/gentoo/vdb_repository.cc @@ -1570,7 +1570,8 @@ VDBRepository::do_category_names_containing_package(const PackageNamePart & p) c bool VDBRepository::is_suitable_destination_for(const PackageDatabaseEntry & e) const { - return _imp->env->package_database()->fetch_repository(e.repository)->format() == "ebuild"; + std::string f(_imp->env->package_database()->fetch_repository(e.repository)->format()); + return f == "ebuild" || f == "ebin"; } bool diff --git a/paludis/repositories/gentoo/vdb_version_metadata.cc b/paludis/repositories/gentoo/vdb_version_metadata.cc index c5e3171a8..c1290b84d 100644 --- a/paludis/repositories/gentoo/vdb_version_metadata.cc +++ b/paludis/repositories/gentoo/vdb_version_metadata.cc @@ -32,6 +32,7 @@ VDBVersionMetadata::VDBVersionMetadata() : .license_interface(this) .virtual_interface(0) .cran_interface(0) + .ebin_interface(0) ), VersionMetadataDepsInterface(&PortageDepParser::parse_depend), VersionMetadataLicenseInterface(&PortageDepParser::parse_license) @@ -53,6 +54,7 @@ VDBVirtualVersionMetadata::VDBVirtualVersionMetadata(const SlotName & s, .license_interface(0) .virtual_interface(this) .cran_interface(0) + .ebin_interface(0) ), VersionMetadataDepsInterface(&PortageDepParser::parse_depend), VersionMetadataVirtualInterface(e) diff --git a/paludis/tasks/install_task.cc b/paludis/tasks/install_task.cc index a25b77891..bc2e195fb 100644 --- a/paludis/tasks/install_task.cc +++ b/paludis/tasks/install_task.cc @@ -41,6 +41,7 @@ namespace paludis std::list<std::string> raw_targets; std::tr1::shared_ptr<AllDepAtom> targets; std::tr1::shared_ptr<std::string> add_to_world_atom; + std::tr1::shared_ptr<const DestinationsCollection> destinations; bool pretend; bool preserve_world; @@ -48,13 +49,15 @@ namespace paludis bool had_set_targets; bool had_package_targets; - Implementation<InstallTask>(Environment * const e, const DepListOptions & o) : + Implementation<InstallTask>(Environment * const e, const DepListOptions & o, + std::tr1::shared_ptr<const DestinationsCollection> d) : env(e), dep_list(e, o), current_dep_list_entry(dep_list.begin()), install_options(false, false, ido_none, false, std::tr1::shared_ptr<Repository>()), uninstall_options(false), targets(new AllDepAtom), + destinations(d), pretend(false), preserve_world(false), had_set_targets(false), @@ -64,8 +67,9 @@ namespace paludis }; } -InstallTask::InstallTask(Environment * const env, const DepListOptions & options) : - PrivateImplementationPattern<InstallTask>(new Implementation<InstallTask>(env, options)) +InstallTask::InstallTask(Environment * const env, const DepListOptions & options, + const std::tr1::shared_ptr<const DestinationsCollection> d) : + PrivateImplementationPattern<InstallTask>(new Implementation<InstallTask>(env, options, d)) { } @@ -177,7 +181,7 @@ InstallTask::execute() /* build up our dep list */ on_build_deplist_pre(); - _imp->dep_list.add(_imp->targets, _imp->env->default_destinations()); + _imp->dep_list.add(_imp->targets, _imp->destinations); on_build_deplist_post(); /* we're about to display our task list */ diff --git a/paludis/tasks/install_task.hh b/paludis/tasks/install_task.hh index 77f39c6f7..b4ab0cdb1 100644 --- a/paludis/tasks/install_task.hh +++ b/paludis/tasks/install_task.hh @@ -43,7 +43,8 @@ namespace paludis ///\name Basic operations ///\{ - InstallTask(Environment * const env, const DepListOptions & options); + InstallTask(Environment * const env, const DepListOptions & options, + std::tr1::shared_ptr<const DestinationsCollection> destinations); ///\} diff --git a/paludis/util/pstream.cc b/paludis/util/pstream.cc index 130a1b604..edecfc8ed 100644 --- a/paludis/util/pstream.cc +++ b/paludis/util/pstream.cc @@ -91,6 +91,7 @@ PStreamInBuf::PStreamInBuf(const Command & cmd) : close(PStream::stderr_close_fd); } + cmd.echo_to_stderr(); Log::get_instance()->message(ll_debug, lc_no_context, "execl /bin/sh -c " + cmd.command()); execl("/bin/sh", "sh", "-c", cmd.command().c_str(), static_cast<char *>(0)); throw PStreamError("execl /bin/sh -c '" + cmd.command() + "' failed:" diff --git a/paludis/util/system.cc b/paludis/util/system.cc index b506dd5fc..ce63a8fee 100644 --- a/paludis/util/system.cc +++ b/paludis/util/system.cc @@ -29,6 +29,7 @@ #include <unistd.h> #include <errno.h> #include <map> +#include <iostream> #include "config.h" /** \file @@ -138,13 +139,15 @@ namespace paludis std::string command; std::map<std::string, std::string> setenv_values; std::string chdir; + bool echo_to_stderr; Implementation(const std::string & c, const std::map<std::string, std::string> & s = (std::map<std::string, std::string>()), - const std::string & d = "") : + const std::string & d = "", bool e = false) : command(c), setenv_values(s), - chdir(d) + chdir(d), + echo_to_stderr(e) { } }; @@ -162,7 +165,7 @@ Command::Command(const char * const s) : Command::Command(const Command & other) : PrivateImplementationPattern<Command>(new Implementation<Command>(other._imp->command, - other._imp->setenv_values, other._imp->chdir)) + other._imp->setenv_values, other._imp->chdir, other._imp->echo_to_stderr)) { } @@ -171,7 +174,7 @@ Command::operator= (const Command & other) { if (this != &other) _imp.reset(new Implementation<Command>(other._imp->command, other._imp->setenv_values, - other._imp->chdir)); + other._imp->chdir, other._imp->echo_to_stderr)); return *this; } @@ -242,6 +245,7 @@ paludis::run_command(const Command & cmd) close(stderr_close_fd); } + cmd.echo_to_stderr(); Log::get_instance()->message(ll_debug, lc_no_context, "execl /bin/sh -c " + cmd.command()); execl("/bin/sh", "sh", "-c", cmd.command().c_str(), static_cast<char *>(0)); throw RunCommandError("execl /bin/sh -c '" + cmd.command() + "' failed:" @@ -284,3 +288,19 @@ Command::end_setenvs() const return Iterator(_imp->setenv_values.end()); } +void +Command::echo_to_stderr() const +{ + if (! _imp->echo_to_stderr) + return; + + std::cerr << "/bin/sh -c " << command().c_str() << std::endl; +} + +Command & +Command::with_echo_to_stderr() +{ + _imp->echo_to_stderr = true; + return *this; +} + diff --git a/paludis/util/system.hh b/paludis/util/system.hh index a1483dca4..2798cc8fd 100644 --- a/paludis/util/system.hh +++ b/paludis/util/system.hh @@ -107,9 +107,11 @@ namespace paludis Command & with_chdir(const FSEntry &); Command & with_setenv(const std::string &, const std::string &); Command & with_sandbox(); + Command & with_echo_to_stderr(); std::string command() const; std::string chdir() const; + void echo_to_stderr() const; typedef libwrapiter::ForwardIterator<Command, const std::pair<const std::string, std::string> > Iterator; Iterator begin_setenvs() const; diff --git a/paludis/version_metadata.cc b/paludis/version_metadata.cc index 43fdd75bc..4ea5caa3e 100644 --- a/paludis/version_metadata.cc +++ b/paludis/version_metadata.cc @@ -98,3 +98,7 @@ VersionMetadataEbuildInterface::VersionMetadataEbuildInterface() { } +VersionMetadataEbinInterface::VersionMetadataEbinInterface() +{ +} + diff --git a/paludis/version_metadata.hh b/paludis/version_metadata.hh index 59128e556..af353a8bd 100644 --- a/paludis/version_metadata.hh +++ b/paludis/version_metadata.hh @@ -37,6 +37,7 @@ namespace paludis { class VersionMetadataEbuildInterface; + class VersionMetadataEbinInterface; class VersionMetadataCRANInterface; class VersionMetadataDepsInterface; class VersionMetadataOriginsInterface; diff --git a/paludis/version_metadata.sr b/paludis/version_metadata.sr index 98ab04a16..0eddbc887 100644 --- a/paludis/version_metadata.sr +++ b/paludis/version_metadata.sr @@ -4,6 +4,7 @@ make_class_VersionMetadataCapabilities() { key ebuild_interface "VersionMetadataEbuildInterface *" + key ebin_interface "VersionMetadataEbinInterface *" key cran_interface "VersionMetadataCRANInterface *" key deps_interface "VersionMetadataDepsInterface *" key origins_interface "VersionMetadataOriginsInterface *" @@ -166,6 +167,26 @@ END END } +make_class_VersionMetadataEbinInterface() +{ + key bin_uri std::string + + extra_constructors <<END + VersionMetadataEbinInterface(); +END + + allow_named_args + + doxygen_comment << "END" + /** + * Version metadata for ebins. + * + * \see VersionMetadata + * \ingroup grpversions + */ +END +} + make_class_VersionMetadataCRANInterface() { key keywords std::string diff --git a/src/clients/contrarius/install.cc b/src/clients/contrarius/install.cc index 7937b850f..dce5d80af 100644 --- a/src/clients/contrarius/install.cc +++ b/src/clients/contrarius/install.cc @@ -54,7 +54,8 @@ namespace { public: OurInstallTask(const DepListOptions & options) : - ConsoleInstallTask(DefaultEnvironment::get_instance(), options) + ConsoleInstallTask(DefaultEnvironment::get_instance(), options, + DefaultEnvironment::get_instance()->default_destinations()) { } diff --git a/src/clients/gtkpaludis/install.cc b/src/clients/gtkpaludis/install.cc index cb5fabb6b..5541545a7 100644 --- a/src/clients/gtkpaludis/install.cc +++ b/src/clients/gtkpaludis/install.cc @@ -34,7 +34,7 @@ namespace paludis } OurInstallTask::OurInstallTask() : - InstallTask(DefaultEnvironment::get_instance(), DepListOptions()), + InstallTask(DefaultEnvironment::get_instance(), DepListOptions(), DefaultEnvironment::get_instance()->default_destinations()), PrivateImplementationPattern<OurInstallTask>(new Implementation<OurInstallTask>) { } diff --git a/src/clients/paludis/command_line.cc b/src/clients/paludis/command_line.cc index c548ba2b9..243284f29 100644 --- a/src/clients/paludis/command_line.cc +++ b/src/clients/paludis/command_line.cc @@ -78,6 +78,7 @@ CommandLine::CommandLine() : install_args(this, "Install, Uninstall options", "Options which are relevant for --install, --uninstall or --uninstall-unused."), a_pretend(&install_args, "pretend", 'p', "Pretend only"), + a_destinations(&install_args, "destinations", 'd', "Use specified destinations instead of defaults"), a_preserve_world(&install_args, "preserve-world", '1', "Don't modify the world file"), a_add_to_world_atom(&install_args, "add-to-world-atom", '\0', "Use this atom, rather than all targets, for updating world (for resume commands)"), diff --git a/src/clients/paludis/command_line.hh b/src/clients/paludis/command_line.hh index a99f5d336..13a35ca21 100644 --- a/src/clients/paludis/command_line.hh +++ b/src/clients/paludis/command_line.hh @@ -191,6 +191,9 @@ class CommandLine : /// --pretend paludis::args::SwitchArg a_pretend; + /// --destinations + paludis::args::StringSetArg a_destinations; + /// --preserve-world paludis::args::SwitchArg a_preserve_world; diff --git a/src/clients/paludis/install.cc b/src/clients/paludis/install.cc index 5cd77cac3..f3a00ed52 100644 --- a/src/clients/paludis/install.cc +++ b/src/clients/paludis/install.cc @@ -39,6 +39,7 @@ #include <paludis/tasks/install_task.hh> #include <paludis/tasks/exceptions.hh> #include <paludis/util/fd_output_stream.hh> +#include <paludis/util/collection_concrete.hh> #include <paludis/util/log.hh> #include <paludis/util/tokeniser.hh> #include <paludis/util/system.hh> @@ -143,8 +144,9 @@ namespace public ConsoleInstallTask { public: - OurInstallTask(const DepListOptions & options) : - ConsoleInstallTask(DefaultEnvironment::get_instance(), options) + OurInstallTask(const DepListOptions & options, + std::tr1::shared_ptr<const DestinationsCollection> destinations) : + ConsoleInstallTask(DefaultEnvironment::get_instance(), options, destinations) { } @@ -460,7 +462,30 @@ do_install() (CommandLine::get_instance()->a_show_reasons.argument() == "full")) options.dependency_tags = true; - OurInstallTask task(options); + std::tr1::shared_ptr<const DestinationsCollection> destinations; + if (CommandLine::get_instance()->a_destinations.specified()) + { + Context local_context("When building destinations collection:"); + + std::tr1::shared_ptr<DestinationsCollection> d(new DestinationsCollection::Concrete); + for (args::StringSetArg::Iterator i(CommandLine::get_instance()->a_destinations.begin_args()), + i_end(CommandLine::get_instance()->a_destinations.end_args()) ; + i != i_end ; ++i) + { + std::tr1::shared_ptr<Repository> repo(DefaultEnvironment::get_instance()->package_database()->fetch_repository( + RepositoryName(*i))); + if (repo->destination_interface) + d->insert(repo); + else + throw args::DoHelp("--destinations argument '" + *i + "' does not provide a destinations interface"); + } + + destinations = d; + } + else + destinations = DefaultEnvironment::get_instance()->default_destinations(); + + OurInstallTask task(options, destinations); task.set_no_config_protect(CommandLine::get_instance()->a_no_config_protection.specified()); task.set_fetch_only(CommandLine::get_instance()->a_fetch.specified()); task.set_pretend(CommandLine::get_instance()->a_pretend.specified()); diff --git a/src/output/console_install_task.cc b/src/output/console_install_task.cc index 96dc929ce..1ca52a1dd 100644 --- a/src/output/console_install_task.cc +++ b/src/output/console_install_task.cc @@ -66,8 +66,9 @@ UseDescriptionComparator::operator() (const UseDescription & lhs, const UseDescr } ConsoleInstallTask::ConsoleInstallTask(Environment * const env, - const DepListOptions & options) : - InstallTask(env, options), + const DepListOptions & options, + std::tr1::shared_ptr<const DestinationsCollection> d) : + InstallTask(env, options, d), _all_tags(new SortedCollection<DepTagEntry>::Concrete), _all_use_descriptions(new SortedCollection<UseDescription, UseDescriptionComparator>::Concrete), _all_expand_prefixes(new UseFlagNameCollection::Concrete) @@ -220,6 +221,7 @@ ConsoleInstallTask::on_display_merge_list_entry(const DepListEntry & d) display_merge_list_entry_slot(d, m); + display_merge_list_entry_destination(d, m); display_merge_list_entry_status_and_update_counts(d, existing, existing_slot, m); display_merge_list_entry_use(d, existing, existing_slot, m); display_merge_list_entry_tags(d, m); @@ -980,6 +982,28 @@ ConsoleInstallTask::display_merge_list_entry_tags(const DepListEntry & d, const } void +ConsoleInstallTask::display_merge_list_entry_destination(const DepListEntry & d, const DisplayMode m) +{ + if (! d.destination) + return; + + output_no_endl(" -> "); + + switch (m) + { + case normal_entry: + case suggested_entry: + case error_entry: + output_no_endl(render_as_repository_name(stringify(d.destination->name()))); + break; + + case unimportant_entry: + output_no_endl(render_as_unimportant(stringify(d.destination->name()))); + break; + } +} + +void ConsoleInstallTask::display_merge_list_entry_end(const DepListEntry &, const DisplayMode) { output_endl(); diff --git a/src/output/console_install_task.hh b/src/output/console_install_task.hh index 16ad01e39..1224d9621 100644 --- a/src/output/console_install_task.hh +++ b/src/output/console_install_task.hh @@ -121,7 +121,8 @@ namespace paludis const PackageDatabaseEntry &, UseDescriptionState); protected: - ConsoleInstallTask(Environment * const env, const DepListOptions & options); + ConsoleInstallTask(Environment * const env, const DepListOptions & options, + std::tr1::shared_ptr<const DestinationsCollection>); public: virtual void on_build_deplist_pre(); @@ -189,6 +190,7 @@ namespace paludis std::tr1::shared_ptr<const PackageDatabaseEntryCollection>, std::tr1::shared_ptr<const PackageDatabaseEntryCollection>, const DisplayMode); virtual void display_merge_list_entry_tags(const DepListEntry &, const DisplayMode); + virtual void display_merge_list_entry_destination(const DepListEntry &, const DisplayMode); virtual void display_merge_list_entry_end(const DepListEntry &, const DisplayMode); virtual void display_merge_list_entry_mask_reasons(const DepListEntry &); |