aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-12-12 13:50:00 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-12-12 13:49:41 +0000
commit5348675092507446129d6ea2b886185c3e0ec613 (patch)
treea86b3dbf5fcc4993d85ab2789a68c95bba6505e0
parent32f24ca833826411227e348fa53d75f388456eb1 (diff)
downloadpaludis-5348675092507446129d6ea2b886185c3e0ec613.tar.gz
paludis-5348675092507446129d6ea2b886185c3e0ec613.tar.xz
Support profile eapi files
-rw-r--r--paludis/repositories/e/e_repository.cc80
-rw-r--r--paludis/repositories/e/e_repository.hh2
-rw-r--r--paludis/repositories/e/e_repository_news.cc3
-rw-r--r--paludis/repositories/e/e_repository_params.hh4
-rw-r--r--paludis/repositories/e/e_repository_profile.cc111
-rw-r--r--paludis/repositories/e/e_repository_profile_file.cc42
-rw-r--r--paludis/repositories/e/e_repository_profile_file.hh13
-rw-r--r--paludis/repositories/e/info_metadata_key.cc58
-rw-r--r--paludis/repositories/e/info_metadata_key.hh5
9 files changed, 207 insertions, 111 deletions
diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc
index 59424e8..0760351 100644
--- a/paludis/repositories/e/e_repository.cc
+++ b/paludis/repositories/e/e_repository.cc
@@ -115,6 +115,7 @@ typedef std::tr1::unordered_map<QualifiedPackageName,
typedef std::tr1::unordered_multimap<std::string, std::string, Hash<std::string> > MirrorMap;
typedef std::tr1::unordered_map<QualifiedPackageName, std::tr1::shared_ptr<const PackageDepSpec>, Hash<QualifiedPackageName> > VirtualsMap;
typedef std::list<RepositoryEInterface::ProfilesDescLine> ProfilesDesc;
+typedef std::map<FSEntry, std::string> EAPIForFileMap;
namespace
{
@@ -170,6 +171,7 @@ namespace paludis
Mutex use_desc_mutex;
Mutex profile_ptr_mutex;
Mutex news_ptr_mutex;
+ Mutex eapi_for_file_mutex;
};
ERepository * const repo;
@@ -201,6 +203,8 @@ namespace paludis
mutable std::tr1::shared_ptr<ERepositoryEntries> entries_ptr;
mutable std::tr1::shared_ptr<Layout> layout;
+ mutable EAPIForFileMap eapi_for_file_map;
+
Implementation(ERepository * const, const ERepositoryParams &, std::tr1::shared_ptr<Mutexes> = make_shared_ptr(new Mutexes));
~Implementation();
@@ -227,7 +231,7 @@ namespace paludis
std::tr1::shared_ptr<const MetadataCollectionKey<Sequence<std::string> > > master_repositories_key;
std::tr1::shared_ptr<const MetadataValueKey<std::string> > eapi_when_unknown_key;
std::tr1::shared_ptr<const MetadataValueKey<std::string> > eapi_when_unspecified_key;
- std::tr1::shared_ptr<const MetadataValueKey<std::string> > profile_eapi_key;
+ std::tr1::shared_ptr<const MetadataValueKey<std::string> > profile_eapi_when_unspecified_key;
std::tr1::shared_ptr<const MetadataValueKey<std::string> > use_manifest_key;
std::tr1::shared_ptr<const MetadataSectionKey> info_pkgs_key;
std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > info_vars_key;
@@ -293,16 +297,15 @@ namespace paludis
"eapi_when_unknown", "eapi_when_unknown", mkt_normal, params.eapi_when_unknown())),
eapi_when_unspecified_key(new LiteralMetadataValueKey<std::string> (
"eapi_when_unspecified", "eapi_when_unspecified", mkt_normal, params.eapi_when_unspecified())),
- profile_eapi_key(new LiteralMetadataValueKey<std::string> (
- "profile_eapi", "profile_eapi", mkt_normal, params.profile_eapi())),
+ profile_eapi_when_unspecified_key(new LiteralMetadataValueKey<std::string> (
+ "profile_eapi_when_unspecified", "profile_eapi_when_unspecified", mkt_normal, params.profile_eapi_when_unspecified())),
use_manifest_key(new LiteralMetadataValueKey<std::string> (
"use_manifest", "use_manifest", mkt_normal, stringify(params.use_manifest()))),
info_pkgs_key(layout->info_packages_files()->end() != std::find_if(layout->info_packages_files()->begin(),
layout->info_packages_files()->end(),
std::tr1::bind(std::tr1::mem_fn(&FSEntry::is_regular_file_or_symlink_to_regular_file),
std::tr1::placeholders::_1)) ?
- make_shared_ptr(new InfoPkgsMetadataKey(params.environment(), layout->info_packages_files(),
- params.profile_eapi())) :
+ make_shared_ptr(new InfoPkgsMetadataKey(params.environment(), layout->info_packages_files(), repo)) :
std::tr1::shared_ptr<InfoPkgsMetadataKey>()
),
info_vars_key(layout->info_variables_files()->end() != std::find_if(layout->info_variables_files()->begin(),
@@ -506,7 +509,7 @@ ERepository::_add_metadata_keys() const
add_metadata_key(_imp->builddir_key);
add_metadata_key(_imp->eapi_when_unknown_key);
add_metadata_key(_imp->eapi_when_unspecified_key);
- add_metadata_key(_imp->profile_eapi_key);
+ add_metadata_key(_imp->profile_eapi_when_unspecified_key);
if (_imp->master_repositories_key)
add_metadata_key(_imp->master_repositories_key);
add_metadata_key(_imp->use_manifest_key);
@@ -561,26 +564,24 @@ ERepository::repository_masked(const PackageID & id) const
using namespace std::tr1::placeholders;
std::tr1::shared_ptr<const FSEntrySequence> repository_mask_files(_imp->layout->repository_mask_files());
- ProfileFile<MaskFile> repository_mask_file;
+ ProfileFile<MaskFile> repository_mask_file(this);
std::for_each(repository_mask_files->begin(), repository_mask_files->end(),
std::tr1::bind(&ProfileFile<MaskFile>::add_file, std::tr1::ref(repository_mask_file), _1));
for (ProfileFile<MaskFile>::ConstIterator
- line(repository_mask_file.begin()), line_end(repository_mask_file.end()) ;
+ line(repository_mask_file.begin()), line_end(repository_mask_file.end()) ;
line != line_end ; ++line)
{
try
{
std::tr1::shared_ptr<const PackageDepSpec> a(new PackageDepSpec(parse_elike_package_dep_spec(
- line->first,
- EAPIData::get_instance()->eapi_from_string(
- _imp->params.profile_eapi())->supported()->package_dep_spec_parse_options(),
+ line->second.first, line->first->supported()->package_dep_spec_parse_options(),
std::tr1::shared_ptr<const PackageID>())));
if (a->package_ptr())
- _imp->repo_mask[*a->package_ptr()].push_back(std::make_pair(a, line->second));
+ _imp->repo_mask[*a->package_ptr()].push_back(std::make_pair(a, line->second.second));
else
Log::get_instance()->message("e.package_mask.bad_spec", ll_warning, lc_context)
- << "Loading package mask spec '" << line->first << "' failed because specification does not restrict to a "
+ << "Loading package mask spec '" << line->second.first << "' failed because specification does not restrict to a "
"unique package";
}
catch (const InternalError &)
@@ -590,7 +591,7 @@ ERepository::repository_masked(const PackageID & id) const
catch (const Exception & e)
{
Log::get_instance()->message("e.package_mask.bad_spec", ll_warning, lc_context) << "Loading package mask spec '"
- << line->first << "' failed due to exception '" << e.message() << "' ("
+ << line->second.first << "' failed due to exception '" << e.message() << "' ("
<< e.what() << ")";
}
}
@@ -1231,15 +1232,17 @@ ERepository::make_manifest(const QualifiedPackageName & qpn)
std::string
ERepository::accept_keywords_variable() const
{
- return EAPIData::get_instance()->eapi_from_string(params().profile_eapi())->supported()
- ->ebuild_environment_variables()->env_accept_keywords();
+ return EAPIData::get_instance()->eapi_from_string(
+ eapi_for_file(*_imp->profiles_key->value()->begin())
+ )->supported()->ebuild_environment_variables()->env_accept_keywords();
}
std::string
ERepository::arch_variable() const
{
- return EAPIData::get_instance()->eapi_from_string(params().profile_eapi())->supported()
- ->ebuild_environment_variables()->env_arch();
+ return EAPIData::get_instance()->eapi_from_string(
+ eapi_for_file(*_imp->profiles_key->value()->begin())
+ )->supported()->ebuild_environment_variables()->env_arch();
}
void
@@ -1470,7 +1473,15 @@ ERepository::repository_factory_create(
env->distribution()))->default_eapi_when_unspecified();
}
- std::string profile_eapi(f("profile_eapi"));
+ std::string profile_eapi(f("profile_eapi_when_unspecified"));
+ if (profile_eapi.empty())
+ {
+ profile_eapi = f("profile_eapi");
+ if (! profile_eapi.empty())
+ Log::get_instance()->message("e.ebuild.configuration.profile_eapi", ll_warning, lc_context) <<
+ "Key 'profile_eapi' in '" + f("repo_file") + "' is deprecated, use profile_eapi_when_unspecified";
+ }
+
if (profile_eapi.empty())
{
if (! layout_conf
@@ -1566,7 +1577,7 @@ ERepository::repository_factory_create(
value_for<n::master_repositories>(master_repositories),
value_for<n::names_cache>(FSEntry(names_cache).realpath_if_exists()),
value_for<n::newsdir>(FSEntry(newsdir).realpath_if_exists()),
- value_for<n::profile_eapi>(profile_eapi),
+ value_for<n::profile_eapi_when_unspecified>(profile_eapi),
value_for<n::profiles>(profiles),
value_for<n::securitydir>(FSEntry(securitydir).realpath_if_exists()),
value_for<n::setsdir>(FSEntry(setsdir).realpath_if_exists()),
@@ -1622,3 +1633,32 @@ ERepository::use_desc() const
return _imp->use_desc;
}
+const std::string
+ERepository::eapi_for_file(const FSEntry & f) const
+{
+ FSEntry dir(f.dirname());
+ Lock lock(_imp->mutexes->eapi_for_file_mutex);
+ EAPIForFileMap::const_iterator i(_imp->eapi_for_file_map.find(dir));
+ if (i == _imp->eapi_for_file_map.end())
+ {
+ Context context("When finding the EAPI to use for file '" + stringify(f) + "':");
+ if ((dir / "eapi").is_regular_file_or_symlink_to_regular_file())
+ {
+ LineConfigFile file(dir / "eapi", LineConfigFileOptions() + lcfo_disallow_continuations);
+ if (file.begin() == file.end())
+ {
+ Log::get_instance()->message("e.ebuild.profile_eapi_file.empty", ll_warning, lc_no_context)
+ << "File '" << (dir / "eapi") << "' has no content";
+ i = _imp->eapi_for_file_map.insert(std::make_pair(
+ dir, _imp->params.profile_eapi_when_unspecified())).first;
+ }
+ else
+ i = _imp->eapi_for_file_map.insert(std::make_pair(dir, *file.begin())).first;
+ }
+ else
+ i = _imp->eapi_for_file_map.insert(std::make_pair(
+ dir, _imp->params.profile_eapi_when_unspecified())).first;
+ }
+ return i->second;
+}
+
diff --git a/paludis/repositories/e/e_repository.hh b/paludis/repositories/e/e_repository.hh
index 2151fb8..a301f1b 100644
--- a/paludis/repositories/e/e_repository.hh
+++ b/paludis/repositories/e/e_repository.hh
@@ -234,6 +234,8 @@ namespace paludis
const std::tr1::shared_ptr<const Set<UnprefixedChoiceName> > arch_flags() const PALUDIS_ATTRIBUTE((warn_unused_result));
const std::tr1::shared_ptr<const UseDesc> use_desc() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ const std::string eapi_for_file(const FSEntry &) const PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/paludis/repositories/e/e_repository_news.cc b/paludis/repositories/e/e_repository_news.cc
index 7ae0435..cac18a6 100644
--- a/paludis/repositories/e/e_repository_news.cc
+++ b/paludis/repositories/e/e_repository_news.cc
@@ -142,7 +142,8 @@ ERepositoryNews::update_news() const
if (! (*_imp->environment)[selection::SomeArbitraryVersion(
generator::Matches(PackageDepSpec(parse_elike_package_dep_spec(*i,
erepository::EAPIData::get_instance()->eapi_from_string(
- _imp->e_repository->params().profile_eapi())->supported()->package_dep_spec_parse_options(),
+ _imp->e_repository->params().profile_eapi_when_unspecified())
+ ->supported()->package_dep_spec_parse_options(),
std::tr1::shared_ptr<const PackageID>())), MatchPackageOptions()) |
filter::SupportsAction<InstalledAction>())]->empty())
local_show = true;
diff --git a/paludis/repositories/e/e_repository_params.hh b/paludis/repositories/e/e_repository_params.hh
index c267bbf..a0e19c3 100644
--- a/paludis/repositories/e/e_repository_params.hh
+++ b/paludis/repositories/e/e_repository_params.hh
@@ -58,7 +58,7 @@ namespace paludis
struct master_repositories;
struct names_cache;
struct newsdir;
- struct profile_eapi;
+ struct profile_eapi_when_unspecified;
struct profiles;
struct securitydir;
struct setsdir;
@@ -94,7 +94,7 @@ namespace paludis
NamedValue<n::master_repositories, std::tr1::shared_ptr<const ERepositorySequence> > master_repositories;
NamedValue<n::names_cache, FSEntry> names_cache;
NamedValue<n::newsdir, FSEntry> newsdir;
- NamedValue<n::profile_eapi, std::string> profile_eapi;
+ NamedValue<n::profile_eapi_when_unspecified, std::string> profile_eapi_when_unspecified;
NamedValue<n::profiles, std::tr1::shared_ptr<const FSEntrySequence> > profiles;
NamedValue<n::securitydir, FSEntry> securitydir;
NamedValue<n::setsdir, FSEntry> setsdir;
diff --git a/paludis/repositories/e/e_repository_profile.cc b/paludis/repositories/e/e_repository_profile.cc
index 674f9d2..3644bea 100644
--- a/paludis/repositories/e/e_repository_profile.cc
+++ b/paludis/repositories/e/e_repository_profile.cc
@@ -59,6 +59,7 @@
#include <ctype.h>
using namespace paludis;
+using namespace paludis::erepository;
template class WrappedForwardIterator<ERepositoryProfile::VirtualsConstIteratorTag,
const std::pair<const QualifiedPackageName, std::tr1::shared_ptr<const PackageDepSpec> > >;
@@ -113,19 +114,19 @@ namespace paludis
void load_profile_make_defaults(const FSEntry & dir);
void load_basic_use_file(const FSEntry & file, FlagStatusMap & m);
- void load_spec_use_file(const FSEntry & file, PackageFlagStatusMapList & m);
+ void load_spec_use_file(const EAPI &, const FSEntry & file, PackageFlagStatusMapList & m);
void add_use_expand_to_use();
void fish_out_use_expand_names();
void make_vars_from_file_vars();
void handle_profile_arch_var(const std::string &);
- void load_special_make_defaults_vars();
+ void load_special_make_defaults_vars(const FSEntry &);
- erepository::ProfileFile<LineConfigFile> packages_file;
- erepository::ProfileFile<LineConfigFile> virtuals_file;
- erepository::ProfileFile<erepository::MaskFile> package_mask_file;
+ ProfileFile<LineConfigFile> packages_file;
+ ProfileFile<LineConfigFile> virtuals_file;
+ ProfileFile<MaskFile> package_mask_file;
- bool is_incremental(const std::string & s) const;
+ bool is_incremental(const EAPI &, const std::string & s) const;
public:
///\name General variables
@@ -182,6 +183,9 @@ namespace paludis
Implementation(const Environment * const e, const ERepository * const p,
const RepositoryName & name, const FSEntrySequence & dirs,
const std::string & arch_var_if_special) :
+ packages_file(p),
+ virtuals_file(p),
+ package_mask_file(p),
env(e),
repository(p),
system_packages(new ConstTreeSequence<SetSpecTree, AllDepSpec>(
@@ -191,6 +195,10 @@ namespace paludis
use_expand_hidden(new Set<std::string>)
{
Context context("When loading profiles '" + join(dirs.begin(), dirs.end(), "' '") + "' for repository '" + stringify(name) + "':");
+
+ if (dirs.empty())
+ throw ERepositoryConfigurationError("No profiles directories specified");
+
load_environment();
for (FSEntrySequence::ConstIterator d(dirs.begin()), d_end(dirs.end()) ;
@@ -207,7 +215,7 @@ namespace paludis
}
make_vars_from_file_vars();
- load_special_make_defaults_vars();
+ load_special_make_defaults_vars(*dirs.begin());
add_use_expand_to_use();
fish_out_use_expand_names();
if (! arch_var_if_special.empty())
@@ -241,6 +249,13 @@ Implementation<ERepositoryProfile>::load_profile_directory_recursively(const FSE
return;
}
+ const std::tr1::shared_ptr<const EAPI> eapi(EAPIData::get_instance()->eapi_from_string(
+ repository->eapi_for_file(dir / "use.mask")));
+
+ if (! eapi->supported())
+ throw ERepositoryConfigurationError("Can't use profile directory '" + stringify(dir) +
+ "' because it uses an unsupported EAPI");
+
stacked_values_list.push_back(StackedValues(stringify(dir)));
load_profile_parent(dir);
@@ -248,9 +263,9 @@ Implementation<ERepositoryProfile>::load_profile_directory_recursively(const FSE
load_basic_use_file(dir / "use.mask", stacked_values_list.back().use_mask);
load_basic_use_file(dir / "use.force", stacked_values_list.back().use_force);
- load_spec_use_file(dir / "package.use", stacked_values_list.back().package_use);
- load_spec_use_file(dir / "package.use.mask", stacked_values_list.back().package_use_mask);
- load_spec_use_file(dir / "package.use.force", stacked_values_list.back().package_use_force);
+ load_spec_use_file(*eapi, dir / "package.use", stacked_values_list.back().package_use);
+ load_spec_use_file(*eapi, dir / "package.use.mask", stacked_values_list.back().package_use_mask);
+ load_spec_use_file(*eapi, dir / "package.use.force", stacked_values_list.back().package_use_force);
packages_file.add_file(dir / "packages");
if ((*DistributionData::get_instance()->distribution_from_string(env->distribution())).support_old_style_virtuals())
@@ -312,6 +327,12 @@ Implementation<ERepositoryProfile>::load_profile_make_defaults(const FSEntry & d
if (! (dir / "make.defaults").exists())
return;
+ const std::tr1::shared_ptr<const EAPI> eapi(EAPIData::get_instance()->eapi_from_string(
+ repository->eapi_for_file(dir / "make.defaults")));
+ if (! eapi->supported())
+ throw ERepositoryConfigurationError("Can't use profile directory '" + stringify(dir) +
+ "' because it uses an unsupported EAPI");
+
KeyValueConfigFile file(dir / "make.defaults", KeyValueConfigFileOptions() +
kvcfo_disallow_source + kvcfo_disallow_space_inside_unquoted_values + kvcfo_allow_inline_comments + kvcfo_allow_multiple_assigns_per_line,
&KeyValueConfigFile::no_defaults, &KeyValueConfigFile::no_transformation);
@@ -319,7 +340,7 @@ Implementation<ERepositoryProfile>::load_profile_make_defaults(const FSEntry & d
for (KeyValueConfigFile::ConstIterator k(file.begin()), k_end(file.end()) ;
k != k_end ; ++k)
{
- if (is_incremental(k->first))
+ if (is_incremental(*eapi, k->first))
{
std::list<std::string> val, val_add;
tokenise_whitespace(environment_variables[k->first], std::back_inserter(val));
@@ -344,8 +365,7 @@ Implementation<ERepositoryProfile>::load_profile_make_defaults(const FSEntry & d
environment_variables[k->first] = k->second;
}
- std::string use_expand_var(erepository::EAPIData::get_instance()->eapi_from_string(
- repository->params().profile_eapi())->supported()->ebuild_environment_variables()->env_use_expand());
+ std::string use_expand_var(eapi->supported()->ebuild_environment_variables()->env_use_expand());
try
{
use_expand->clear();
@@ -364,10 +384,15 @@ Implementation<ERepositoryProfile>::load_profile_make_defaults(const FSEntry & d
}
void
-Implementation<ERepositoryProfile>::load_special_make_defaults_vars()
+Implementation<ERepositoryProfile>::load_special_make_defaults_vars(const FSEntry & dir)
{
- std::string use_var(erepository::EAPIData::get_instance()->eapi_from_string(
- repository->params().profile_eapi())->supported()->ebuild_environment_variables()->env_use());
+ const std::tr1::shared_ptr<const EAPI> eapi(EAPIData::get_instance()->eapi_from_string(
+ repository->eapi_for_file(dir / "make.defaults")));
+ if (! eapi->supported())
+ throw ERepositoryConfigurationError("Can't use profile directory '" + stringify(dir) +
+ "' because it uses an unsupported EAPI");
+
+ std::string use_var(eapi->supported()->ebuild_environment_variables()->env_use());
try
{
use.clear();
@@ -390,8 +415,7 @@ Implementation<ERepositoryProfile>::load_special_make_defaults_vars()
<< "Loading '" << use_var << "' failed due to exception: " << e.message() << " (" << e.what() << ")";
}
- std::string use_expand_var(erepository::EAPIData::get_instance()->eapi_from_string(
- repository->params().profile_eapi())->supported()->ebuild_environment_variables()->env_use_expand());
+ std::string use_expand_var(eapi->supported()->ebuild_environment_variables()->env_use_expand());
try
{
use_expand->clear();
@@ -408,8 +432,7 @@ Implementation<ERepositoryProfile>::load_special_make_defaults_vars()
<< "Loading '" << use_expand_var << "' failed due to exception: " << e.message() << " (" << e.what() << ")";
}
- std::string use_expand_hidden_var(erepository::EAPIData::get_instance()->eapi_from_string(
- repository->params().profile_eapi())->supported()->ebuild_environment_variables()->env_use_expand_hidden());
+ std::string use_expand_hidden_var(eapi->supported()->ebuild_environment_variables()->env_use_expand_hidden());
try
{
use_expand_hidden->clear();
@@ -429,16 +452,14 @@ Implementation<ERepositoryProfile>::load_special_make_defaults_vars()
}
bool
-Implementation<ERepositoryProfile>::is_incremental(const std::string & s) const
+Implementation<ERepositoryProfile>::is_incremental(const EAPI & e, const std::string & s) const
{
- std::tr1::shared_ptr<const erepository::EAPI> e(erepository::EAPIData::get_instance()->eapi_from_string(repository->params().profile_eapi()));
-
Context c("When checking whether '" + s + "' is incremental:");
return (! s.empty()) && (
- (s == e->supported()->ebuild_environment_variables()->env_use())
- || (s == e->supported()->ebuild_environment_variables()->env_use_expand())
- || (s == e->supported()->ebuild_environment_variables()->env_use_expand_hidden())
+ (s == e.supported()->ebuild_environment_variables()->env_use())
+ || (s == e.supported()->ebuild_environment_variables()->env_use_expand())
+ || (s == e.supported()->ebuild_environment_variables()->env_use_expand_hidden())
|| s == "CONFIG_PROTECT"
|| s == "CONFIG_PROTECT_MASK"
|| use_expand->end() != use_expand->find(s));
@@ -450,17 +471,16 @@ Implementation<ERepositoryProfile>::make_vars_from_file_vars()
try
{
if (! repository->params().master_repositories())
- for (erepository::ProfileFile<LineConfigFile>::ConstIterator i(packages_file.begin()),
+ for (ProfileFile<LineConfigFile>::ConstIterator i(packages_file.begin()),
i_end(packages_file.end()) ; i != i_end ; ++i)
{
- if (0 != i->compare(0, 1, "*", 0, 1))
+ if (0 != i->second.compare(0, 1, "*", 0, 1))
continue;
- Context context_spec("When parsing '" + *i + "':");
+ Context context_spec("When parsing '" + i->second + "':");
std::tr1::shared_ptr<PackageDepSpec> spec(new PackageDepSpec(
- parse_elike_package_dep_spec(i->substr(1),
- erepository::EAPIData::get_instance()->eapi_from_string(
- repository->params().profile_eapi())->supported()->package_dep_spec_parse_options(),
+ parse_elike_package_dep_spec(i->second.substr(1),
+ i->first->supported()->package_dep_spec_parse_options(),
std::tr1::shared_ptr<const PackageID>())));
spec->set_tag(system_tag);
@@ -481,19 +501,19 @@ Implementation<ERepositoryProfile>::make_vars_from_file_vars()
env->distribution())).support_old_style_virtuals())
try
{
- for (erepository::ProfileFile<LineConfigFile>::ConstIterator line(virtuals_file.begin()), line_end(virtuals_file.end()) ;
+ for (ProfileFile<LineConfigFile>::ConstIterator line(virtuals_file.begin()), line_end(virtuals_file.end()) ;
line != line_end ; ++line)
{
std::vector<std::string> tokens;
- tokenise_whitespace(*line, std::back_inserter(tokens));
+ tokenise_whitespace(line->second, std::back_inserter(tokens));
if (tokens.size() < 2)
continue;
QualifiedPackageName v(tokens[0]);
virtuals.erase(v);
virtuals.insert(std::make_pair(v, std::tr1::shared_ptr<PackageDepSpec>(new PackageDepSpec(
- parse_elike_package_dep_spec(tokens[1], erepository::EAPIData::get_instance()->eapi_from_string(
- repository->params().profile_eapi())->supported()->package_dep_spec_parse_options(),
+ parse_elike_package_dep_spec(tokens[1],
+ line->first->supported()->package_dep_spec_parse_options(),
std::tr1::shared_ptr<const PackageID>())))));
}
}
@@ -507,24 +527,24 @@ Implementation<ERepositoryProfile>::make_vars_from_file_vars()
<< "Loading virtuals failed due to exception: " << e.message() << " (" << e.what() << ")";
}
- for (erepository::ProfileFile<erepository::MaskFile>::ConstIterator line(package_mask_file.begin()), line_end(package_mask_file.end()) ;
+ for (ProfileFile<MaskFile>::ConstIterator line(package_mask_file.begin()), line_end(package_mask_file.end()) ;
line != line_end ; ++line)
{
- if (line->first.empty())
+ if (line->second.first.empty())
continue;
try
{
std::tr1::shared_ptr<const PackageDepSpec> a(new PackageDepSpec(
- parse_elike_package_dep_spec(line->first, erepository::EAPIData::get_instance()->eapi_from_string(
- repository->params().profile_eapi())->supported()->package_dep_spec_parse_options(),
+ parse_elike_package_dep_spec(line->second.first,
+ line->first->supported()->package_dep_spec_parse_options(),
std::tr1::shared_ptr<const PackageID>())));
if (a->package_ptr())
- package_mask[*a->package_ptr()].push_back(std::make_pair(a, line->second));
+ package_mask[*a->package_ptr()].push_back(std::make_pair(a, line->second.second));
else
Log::get_instance()->message("e.profile.package_mask.bad_spec", ll_warning, lc_context)
- << "Loading package.mask spec '" << line->first << "' failed because specification does not restrict to a "
+ << "Loading package.mask spec '" << line->second.first << "' failed because specification does not restrict to a "
"unique package";
}
catch (const InternalError &)
@@ -534,7 +554,7 @@ Implementation<ERepositoryProfile>::make_vars_from_file_vars()
catch (const Exception & e)
{
Log::get_instance()->message("e.profile.package_mask.bad_spec", ll_warning, lc_context)
- << "Loading package.mask spec '" << line->first << "' failed due to exception '" << e.message() << "' ("
+ << "Loading package.mask spec '" << line->second.first << "' failed due to exception '" << e.message() << "' ("
<< e.what() << ")";
}
}
@@ -580,7 +600,7 @@ Implementation<ERepositoryProfile>::load_basic_use_file(const FSEntry & file, Fl
}
void
-Implementation<ERepositoryProfile>::load_spec_use_file(const FSEntry & file, PackageFlagStatusMapList & m)
+Implementation<ERepositoryProfile>::load_spec_use_file(const EAPI & eapi, const FSEntry & file, PackageFlagStatusMapList & m)
{
if (! file.exists())
return;
@@ -599,8 +619,7 @@ Implementation<ERepositoryProfile>::load_spec_use_file(const FSEntry & file, Pac
try
{
std::tr1::shared_ptr<const PackageDepSpec> spec(new PackageDepSpec(
- parse_elike_package_dep_spec(*tokens.begin(), erepository::EAPIData::get_instance()->eapi_from_string(
- repository->params().profile_eapi())->supported()->package_dep_spec_parse_options(),
+ parse_elike_package_dep_spec(*tokens.begin(), eapi.supported()->package_dep_spec_parse_options(),
std::tr1::shared_ptr<const PackageID>())));
PackageFlagStatusMapList::iterator n(m.insert(m.end(), std::make_pair(spec, FlagStatusMap())));
diff --git a/paludis/repositories/e/e_repository_profile_file.cc b/paludis/repositories/e/e_repository_profile_file.cc
index 0346989..89e8afa 100644
--- a/paludis/repositories/e/e_repository_profile_file.cc
+++ b/paludis/repositories/e/e_repository_profile_file.cc
@@ -17,8 +17,11 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "e_repository_profile_file.hh"
-#include "e_repository_mask_file.hh"
+#include <paludis/repositories/e/e_repository_profile_file.hh>
+#include <paludis/repositories/e/e_repository_mask_file.hh>
+#include <paludis/repositories/e/e_repository_exceptions.hh>
+#include <paludis/repositories/e/eapi.hh>
+#include <paludis/repositories/e/e_repository.hh>
#include <paludis/util/log.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/config_file.hh>
@@ -40,7 +43,7 @@ namespace
struct FileEntryTraits;
template<>
- struct FileEntryTraits<std::string>
+ struct FileEntryTraits<const std::string>
{
static const std::string extract_key(const std::string & k)
{
@@ -49,7 +52,7 @@ namespace
};
template <typename F_, typename S_>
- struct FileEntryTraits<std::pair<F_, S_> >
+ struct FileEntryTraits<const std::pair<F_, S_> >
{
static const std::string extract_key(const std::pair<F_, S_> & p)
{
@@ -70,7 +73,7 @@ namespace
template <typename U_>
bool operator() (const U_ & y)
{
- return FileEntryTraits<U_>::extract_key(y) == _x;
+ return FileEntryTraits<typename U_::second_type>::extract_key(y.second) == _x;
}
};
}
@@ -80,11 +83,18 @@ namespace paludis
template <typename F_>
struct Implementation<ProfileFile<F_> >
{
- typedef std::list<typename std::tr1::remove_const<typename std::tr1::remove_reference<
- typename F_::ConstIterator::value_type>::type>::type> Lines;
+ const ERepository * const repository;
+
+ typedef std::list<std::pair<std::tr1::shared_ptr<const EAPI>,
+ const typename std::tr1::remove_reference<typename F_::ConstIterator::value_type>::type> > Lines;
Lines lines;
std::set<std::string> removed;
+
+ Implementation(const ERepository * const r) :
+ repository(r)
+ {
+ }
};
}
@@ -97,11 +107,16 @@ ProfileFile<F_>::add_file(const FSEntry & f)
if (! f.exists())
return;
+ const std::tr1::shared_ptr<const EAPI> eapi(EAPIData::get_instance()->eapi_from_string(
+ this->_imp->repository->eapi_for_file(f)));
+ if (! eapi->supported())
+ throw ERepositoryConfigurationError("Can't use profile file '" + stringify(f) +
+ "' because it uses an unsupported EAPI");
+
F_ file(f, LineConfigFileOptions() + lcfo_disallow_continuations);
for (typename F_::ConstIterator line(file.begin()), line_end(file.end()) ; line != line_end ; ++line)
{
- const std::string & key(FileEntryTraits<typename std::tr1::remove_const<typename std::tr1::remove_reference<
- typename F_::ConstIterator::value_type>::type>::type>::extract_key(*line));
+ const std::string key(FileEntryTraits<const typename std::tr1::remove_reference<typename F_::ConstIterator::value_type>::type>::extract_key(*line));
if (0 == key.compare(0, 1, "-", 0, 1))
{
typename Implementation<ProfileFile>::Lines::iterator i(
@@ -129,13 +144,13 @@ ProfileFile<F_>::add_file(const FSEntry & f)
}
}
else
- this->_imp->lines.push_back(*line);
+ this->_imp->lines.push_back(std::make_pair(eapi, *line));
}
}
template <typename F_>
-ProfileFile<F_>::ProfileFile() :
- PrivateImplementationPattern<ProfileFile>(new Implementation<ProfileFile<F_> >)
+ProfileFile<F_>::ProfileFile(const ERepository * const r) :
+ PrivateImplementationPattern<ProfileFile>(new Implementation<ProfileFile<F_> >(r))
{
}
@@ -159,8 +174,5 @@ ProfileFile<F_>::end() const
}
template class ProfileFile<LineConfigFile>;
-template class WrappedForwardIterator<ProfileFile<LineConfigFile>::ConstIteratorTag, LineConfigFile::ConstIterator::value_type>;
-
template class ProfileFile<MaskFile>;
-template class WrappedForwardIterator<ProfileFile<MaskFile>::ConstIteratorTag, MaskFile::ConstIterator::value_type>;
diff --git a/paludis/repositories/e/e_repository_profile_file.hh b/paludis/repositories/e/e_repository_profile_file.hh
index bd171da..2241fc8 100644
--- a/paludis/repositories/e/e_repository_profile_file.hh
+++ b/paludis/repositories/e/e_repository_profile_file.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2006, 2007, 2008 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
@@ -20,14 +20,18 @@
#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_E_REPOSITORY_PROFILE_FILE_HH
#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_E_REPOSITORY_PROFILE_FILE_HH 1
+#include <paludis/repositories/e/eapi-fwd.hh>
#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/util/attributes.hh>
#include <paludis/util/fs_entry.hh>
#include <paludis/util/wrapped_forward_iterator-fwd.hh>
#include <paludis/mask-fwd.hh>
+#include <tr1/type_traits>
namespace paludis
{
+ struct ERepository;
+
namespace erepository
{
/**
@@ -45,7 +49,7 @@ namespace paludis
///\name Basic operations
///\{
- ProfileFile();
+ ProfileFile(const ERepository * const);
~ProfileFile();
///\}
@@ -59,7 +63,10 @@ namespace paludis
///\{
struct ConstIteratorTag;
- typedef WrappedForwardIterator<ConstIteratorTag, typename F_::ConstIterator::value_type> ConstIterator;
+ typedef WrappedForwardIterator<ConstIteratorTag, const std::pair<
+ std::tr1::shared_ptr<const erepository::EAPI>,
+ const typename std::tr1::remove_reference<
+ typename F_::ConstIterator::value_type>::type> > ConstIterator;
ConstIterator begin() const;
ConstIterator end() const;
diff --git a/paludis/repositories/e/info_metadata_key.cc b/paludis/repositories/e/info_metadata_key.cc
index 655c815..a6f5f35 100644
--- a/paludis/repositories/e/info_metadata_key.cc
+++ b/paludis/repositories/e/info_metadata_key.cc
@@ -19,6 +19,7 @@
#include <paludis/repositories/e/info_metadata_key.hh>
#include <paludis/repositories/e/eapi.hh>
+#include <paludis/repositories/e/e_repository.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/fs_entry.hh>
#include <paludis/util/mutex.hh>
@@ -40,7 +41,7 @@
#include <paludis/environment.hh>
#include <paludis/package_id.hh>
#include <paludis/formatter.hh>
-#include <set>
+#include <map>
#include <algorithm>
#include <tr1/functional>
@@ -68,16 +69,16 @@ namespace paludis
{
const Environment * const env;
const std::tr1::shared_ptr<const FSEntrySequence> locations;
- const std::string eapi;
+ const ERepository * const e_repository;
mutable Mutex mutex;
mutable bool added;
Implementation(const Environment * const e, const std::tr1::shared_ptr<const FSEntrySequence> & l,
- const std::string & p) :
+ const ERepository * const r) :
env(e),
locations(l),
- eapi(p),
+ e_repository(r),
added(false)
{
}
@@ -122,9 +123,10 @@ InfoVarsMetadataKey::value() const
}
InfoPkgsMetadataKey::InfoPkgsMetadataKey(const Environment * const e,
- const std::tr1::shared_ptr<const FSEntrySequence> & f, const std::string & p) :
+ const std::tr1::shared_ptr<const FSEntrySequence> & f,
+ const ERepository * const r) :
MetadataSectionKey("info_pkgs", "Package information", mkt_normal),
- PrivateImplementationPattern<InfoPkgsMetadataKey>(new Implementation<InfoPkgsMetadataKey>(e, f, p)),
+ PrivateImplementationPattern<InfoPkgsMetadataKey>(new Implementation<InfoPkgsMetadataKey>(e, f, r)),
_imp(PrivateImplementationPattern<InfoPkgsMetadataKey>::_imp)
{
}
@@ -140,7 +142,7 @@ InfoPkgsMetadataKey::need_keys_added() const
if (_imp->added)
return;
- std::set<std::string> info_pkgs;
+ std::map<std::string, std::string> info_pkgs;
for (FSEntrySequence::ConstIterator location(_imp->locations->begin()), location_end(_imp->locations->end()) ;
location != location_end ; ++location)
{
@@ -149,31 +151,41 @@ InfoPkgsMetadataKey::need_keys_added() const
if (location->is_regular_file_or_symlink_to_regular_file())
{
+ std::string eapi(_imp->e_repository->eapi_for_file(*location));
LineConfigFile p(*location, LineConfigFileOptions() + lcfo_disallow_continuations);
- std::copy(p.begin(), p.end(), std::inserter(info_pkgs, info_pkgs.begin()));
+ for (LineConfigFile::ConstIterator line(p.begin()), line_end(p.end()) ;
+ line != line_end ; ++line)
+ info_pkgs.insert(std::make_pair(*line, eapi));
}
}
- for (std::set<std::string>::const_iterator i(info_pkgs.begin()), i_end(info_pkgs.end()) ;
+ for (std::map<std::string, std::string>::const_iterator i(info_pkgs.begin()), i_end(info_pkgs.end()) ;
i != i_end ; ++i)
{
+ std::tr1::shared_ptr<const EAPI> eapi(erepository::EAPIData::get_instance()->eapi_from_string(i->second));
std::tr1::shared_ptr<MetadataKey> key;
- std::tr1::shared_ptr<const PackageIDSequence> q((*_imp->env)[selection::AllVersionsSorted(
- generator::Matches(parse_elike_package_dep_spec(*i,
- erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi)->supported()->package_dep_spec_parse_options(),
- std::tr1::shared_ptr<const PackageID>()), MatchPackageOptions()) |
- filter::InstalledAtRoot(_imp->env->root()))]);
-
- if (q->empty())
- key.reset(new LiteralMetadataValueKey<std::string>(*i, *i, mkt_normal, "(none)"));
- else
+
+ if (eapi->supported())
{
- using namespace std::tr1::placeholders;
- std::tr1::shared_ptr<Set<std::string> > s(new Set<std::string>);
- std::transform(indirect_iterator(q->begin()), indirect_iterator(q->end()), s->inserter(),
- std::tr1::bind(std::tr1::mem_fn(&PackageID::canonical_form), _1, idcf_version));
- key.reset(new LiteralMetadataStringSetKey(*i, *i, mkt_normal, s));
+ std::tr1::shared_ptr<const PackageIDSequence> q((*_imp->env)[selection::AllVersionsSorted(
+ generator::Matches(parse_elike_package_dep_spec(i->first,
+ eapi->supported()->package_dep_spec_parse_options(),
+ std::tr1::shared_ptr<const PackageID>()), MatchPackageOptions()) |
+ filter::InstalledAtRoot(_imp->env->root()))]);
+
+ if (q->empty())
+ key.reset(new LiteralMetadataValueKey<std::string>(i->first, i->first, mkt_normal, "(none)"));
+ else
+ {
+ using namespace std::tr1::placeholders;
+ std::tr1::shared_ptr<Set<std::string> > s(new Set<std::string>);
+ std::transform(indirect_iterator(q->begin()), indirect_iterator(q->end()), s->inserter(),
+ std::tr1::bind(std::tr1::mem_fn(&PackageID::canonical_form), _1, idcf_version));
+ key.reset(new LiteralMetadataStringSetKey(i->first, i->first, mkt_normal, s));
+ }
}
+ else
+ key.reset(new LiteralMetadataValueKey<std::string>(i->first, i->first, mkt_normal, "(unknown EAPI)"));
add_metadata_key(key);
}
diff --git a/paludis/repositories/e/info_metadata_key.hh b/paludis/repositories/e/info_metadata_key.hh
index 3ebfe2f..3010c43 100644
--- a/paludis/repositories/e/info_metadata_key.hh
+++ b/paludis/repositories/e/info_metadata_key.hh
@@ -11,6 +11,8 @@
namespace paludis
{
+ struct ERepository;
+
namespace erepository
{
class InfoPkgsMetadataKey :
@@ -25,7 +27,8 @@ namespace paludis
public:
InfoPkgsMetadataKey(const Environment * const e,
- const std::tr1::shared_ptr<const FSEntrySequence> & f, const std::string & p);
+ const std::tr1::shared_ptr<const FSEntrySequence> & f,
+ const ERepository * const);
~InfoPkgsMetadataKey();
};