diff options
-rw-r--r-- | paludis/repositories/e/e_repository.cc | 2 | ||||
-rw-r--r-- | paludis/repositories/e/e_repository_TEST.cc | 30 | ||||
-rwxr-xr-x | paludis/repositories/e/e_repository_TEST_setup.sh | 165 | ||||
-rw-r--r-- | paludis/repositories/e/ebuild.cc | 14 | ||||
-rw-r--r-- | paludis/repositories/e/ebuild_id.cc | 77 | ||||
-rw-r--r-- | paludis/repositories/e/ebuild_id.hh | 2 |
6 files changed, 281 insertions, 9 deletions
diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc index 1e4dbac04..94a3ebc13 100644 --- a/paludis/repositories/e/e_repository.cc +++ b/paludis/repositories/e/e_repository.cc @@ -1700,7 +1700,7 @@ ERepository::make_id(const QualifiedPackageName & q, const FSPath & f) const std::shared_ptr<EbuildID> result(std::make_shared<EbuildID>(q, extract_package_file_version(q, f, eapi), _imp->params.environment(), - name(), f, eapi, + name(), f, eapi, ! suffix_eapi.empty(), _imp->master_mtime, _imp->eclass_mtimes)); return result; } diff --git a/paludis/repositories/e/e_repository_TEST.cc b/paludis/repositories/e/e_repository_TEST.cc index 448fe14c3..b32bab49e 100644 --- a/paludis/repositories/e/e_repository_TEST.cc +++ b/paludis/repositories/e/e_repository_TEST.cc @@ -829,3 +829,33 @@ TEST(ERepository, ManifestCheck) id->perform_action(action); } +TEST(ERepository, ParseEAPI) +{ + TestEnvironment env; + std::shared_ptr<Map<std::string, std::string> > keys(std::make_shared<Map<std::string, std::string>>()); + keys->insert("format", "e"); + keys->insert("names_cache", "/var/empty"); + keys->insert("eapi_when_unspecified", "paludis-1"); + keys->insert("location", stringify(FSPath::cwd() / "e_repository_TEST_dir" / "repo20")); + keys->insert("profiles", stringify(FSPath::cwd() / "e_repository_TEST_dir" / "repo20/profiles/profile")); + keys->insert("builddir", stringify(FSPath::cwd() / "e_repository_TEST_dir" / "build")); + std::shared_ptr<ERepository> repo(std::static_pointer_cast<ERepository>(ERepository::repository_factory_create(&env, + std::bind(from_keys, keys, std::placeholders::_1)))); + env.add_repository(1, repo); + + const std::string eapis[] = { + "0", "0", "paludis-1", "0", "1", "1", "1", "1", "1", "1", + "1", "1", "1", "1", "1", "0", "not-a-real-eapi", "UNKNOWN", "UNKNOWN", "1", + "UNKNOWN", "0", "1", "UNKNOWN", "UNKNOWN", "1", "UNKNOWN", "UNKNOWN", "UNKNOWN", "1", + "0", "UNKNOWN", "UNKNOWN", "exheres-0", "exheres-0", "UNKNOWN", "" + }; + auto ids(env[selection::AllVersionsSorted(generator::Matches( + PackageDepSpec(parse_user_package_dep_spec("category/package", + &env, { })), make_null_shared_ptr(), { }))]); + + int i(0); + for (auto it(ids->begin()), it_end(ids->end()); it_end != it; ++i, ++it) + EXPECT_EQ(eapis[i], std::static_pointer_cast<const MetadataValueKey<std::string> >(*(*it)->find_metadata("EAPI"))->parse_value()) << "(i == " << i << ")"; + EXPECT_EQ("", eapis[i]) << "(i == " << i << ")"; +} + diff --git a/paludis/repositories/e/e_repository_TEST_setup.sh b/paludis/repositories/e/e_repository_TEST_setup.sh index fc7eba6a6..9b24d4a42 100755 --- a/paludis/repositories/e/e_repository_TEST_setup.sh +++ b/paludis/repositories/e/e_repository_TEST_setup.sh @@ -676,5 +676,170 @@ KEYWORDS="test" END cd .. +mkdir -p repo20/profiles/profile || exit 1 +mkdir -p repo20/category/package || exit 1 +cd repo20 || exit 1 +echo test-repo-20 >> profiles/repo_name || exit 1 +echo "category" >> profiles/categories || exit 1 +cat <<END > profiles/profile/make.defaults +ARCH=test +END +spaces=" " +tab=$'\t' +cat <<END > category/package/package-0.ebuild || exit 1 +SLOT="0" +END +cat <<END > category/package/package-1.ebuild || exit 1 +EAPI=0 +SLOT="0" +END +cat <<END > category/package/package-2.ebuild || exit 1 +EAPI= +SLOT="0" +END +cat <<END > category/package/package-3.ebuild || exit 1 +#EAPI=1 +SLOT="0" +END +cat <<END > category/package/package-4.ebuild || exit 1 +EAPI=1 +SLOT="0" +END +cat <<END > category/package/package-5.ebuild || exit 1 + +EAPI=1 +SLOT="0" +END +cat <<END > category/package/package-6.ebuild || exit 1 +${spaces} +EAPI=1 +SLOT="0" +END +cat <<END > category/package/package-7.ebuild || exit 1 +${tab} +EAPI=1 +SLOT="0" +END +cat <<END > category/package/package-8.ebuild || exit 1 +# 123 +EAPI=1 +SLOT="0" +END +cat <<END > category/package/package-9.ebuild || exit 1 + EAPI=1 +SLOT="0" +END +cat <<END > category/package/package-10.ebuild || exit 1 +${tab}EAPI=1 +SLOT="0" +END +cat <<END > category/package/package-11.ebuild || exit 1 +EAPI=1${spaces} +SLOT="0" +END +cat <<END > category/package/package-12.ebuild || exit 1 +EAPI=1${tab} +SLOT="0" +END +cat <<END > category/package/package-13.ebuild || exit 1 +EAPI=1 # 123 +SLOT="0" +END +cat <<END > category/package/package-14.ebuild || exit 1 +EAPI=1${tab}# 123 +SLOT="0" +END +cat <<END > category/package/package-15.ebuild || exit 1 +EAPI=1 123 +SLOT="0" +END +cat <<END > category/package/package-16.ebuild || exit 1 +EAPI=not-a-real-eapi +SLOT="0" +END +cat <<END > category/package/package-17.ebuild || exit 1 +EAPI=@ +SLOT="0" +END +cat <<END > category/package/package-18.ebuild || exit 1 +EAPI=1@ +SLOT="0" +END +cat <<END > category/package/package-19.ebuild || exit 1 +EAPI="1" +SLOT="0" +END +cat <<END > category/package/package-20.ebuild || exit 1 +EAPI="1"123 +SLOT="0" +END +cat <<END > category/package/package-21.ebuild || exit 1 +EAPI="1" 123 +SLOT="0" +END +cat <<END > category/package/package-22.ebuild || exit 1 +EAPI="1" # 123 +SLOT="0" +END +cat <<END > category/package/package-23.ebuild || exit 1 +EAPI="1 +" +SLOT="0" +END +cat <<END > category/package/package-24.ebuild || exit 1 +EAPI="1' +" +SLOT="0" +END +cat <<END > category/package/package-25.ebuild || exit 1 +EAPI='1' +SLOT="0" +END +cat <<END > category/package/package-26.ebuild || exit 1 +EAPI='1 +' +SLOT="0" +END +cat <<END > category/package/package-27.ebuild || exit 1 +EAPI='1" +' +SLOT="0" +END +cat <<END > category/package/package-28.ebuild || exit 1 +EAPI=1 +EAPI=2 +SLOT="0" +END +cat <<END > category/package/package-29.ebuild || exit 1 +EAPI=1 +EAPI=2 +EAPI=1 +SLOT="0" +END +cat <<END > category/package/package-30.ebuild || exit 1 +SLOT="0" +EAPI=0 +END +cat <<END > category/package/package-31.ebuild || exit 1 +SLOT="0" +EAPI=1 +END +cat <<END > category/package/package-32.ebuild || exit 1 +printf -v EAPI 1 +SLOT="0" +END +cat <<END > category/package/package-33.exheres-0 || exit 1 +SLOT="0" +END +cat <<END > category/package/package-34.exheres-0 || exit 1 +EAPI=exheres-0 +SLOT="0" +END +cat <<END > category/package/package-35.exheres-0 || exit 1 +EAPI=1 +SLOT="0" +END +cd .. + cd .. diff --git a/paludis/repositories/e/ebuild.cc b/paludis/repositories/e/ebuild.cc index 2ee973565..dede6c3af 100644 --- a/paludis/repositories/e/ebuild.cc +++ b/paludis/repositories/e/ebuild.cc @@ -512,14 +512,18 @@ EbuildMetadataCommand::load(const std::shared_ptr<const EbuildID> & id) Log::get_instance()->message("e.ebuild.preload_eapi.supported", ll_debug, lc_context) << "ID pre-load EAPI '" << id->eapi()->name() << "' is supported"; - std::string s; - if (! ((s = get(keys, id->eapi()->supported()->ebuild_metadata_variables()->eapi()->name()))).empty()) - id->set_eapi(s); - else + std::string s(get(keys, id->eapi()->supported()->ebuild_metadata_variables()->eapi()->name())); + if (s.empty()) { auto repo(params.environment()->fetch_repository(id->repository_name())); auto e_repo(std::static_pointer_cast<const ERepository>(repo)); - id->set_eapi(e_repo->params().eapi_when_unspecified()); + s = e_repo->params().eapi_when_unspecified(); + } + if (id->eapi()->name() != s) + { + Log::get_instance()->message("e.ebuild.postload_eapi.mismatch", ll_warning, lc_context) + << "Post-source EAPI '" << s << "' does not match pre-source EAPI '" << id->eapi()->name() << "', treating as unknown"; + id->set_eapi(EAPIData::get_instance()->unknown_eapi()->name()); } if (! id->eapi()->supported()) diff --git a/paludis/repositories/e/ebuild_id.cc b/paludis/repositories/e/ebuild_id.cc index ae6ae9773..f2dc1ad92 100644 --- a/paludis/repositories/e/ebuild_id.cc +++ b/paludis/repositories/e/ebuild_id.cc @@ -69,6 +69,7 @@ #include <paludis/util/fs_stat.hh> #include <paludis/util/join.hh> #include <paludis/util/upper_lower.hh> +#include <paludis/util/safe_ifstream.hh> #include <set> #include <iterator> @@ -140,6 +141,7 @@ namespace paludis const RepositoryName repository_name; mutable std::shared_ptr<const EAPI> eapi; const std::string guessed_eapi; + const bool eapi_from_suffix; const time_t master_mtime; const std::shared_ptr<const EclassMtimes> eclass_mtimes; mutable bool has_non_xml_keys; @@ -187,12 +189,13 @@ namespace paludis Imp(const QualifiedPackageName & q, const VersionSpec & v, const Environment * const e, const RepositoryName & r, const FSPath & f, const std::string & g, - const time_t t, const std::shared_ptr<const EclassMtimes> & m) : + const bool es, const time_t t, const std::shared_ptr<const EclassMtimes> & m) : name(q), version(v), environment(e), repository_name(r), guessed_eapi(g), + eapi_from_suffix(es), master_mtime(t), eclass_mtimes(m), has_non_xml_keys(false), @@ -209,9 +212,10 @@ EbuildID::EbuildID(const QualifiedPackageName & q, const VersionSpec & v, const RepositoryName & r, const FSPath & f, const std::string & g, + const bool es, const time_t t, const std::shared_ptr<const EclassMtimes> & m) : - _imp(q, v, e, r, f, g, t, m) + _imp(q, v, e, r, f, g, es, t, m) { } @@ -281,7 +285,7 @@ EbuildID::need_non_xml_keys_added() const _imp->environment->trigger_notifier_callback(NotifierCallbackGeneratingMetadataEvent(repository_name())); - _imp->eapi = EAPIData::get_instance()->eapi_from_string(_imp->guessed_eapi); + _imp->eapi = presource_eapi(); if (_imp->eapi->supported()) { @@ -420,6 +424,73 @@ EbuildID::need_non_xml_keys_added() const add_metadata_key(_imp->choices); } +const std::shared_ptr<const EAPI> +EbuildID::presource_eapi() const +{ + auto guessed(EAPIData::get_instance()->eapi_from_string(_imp->guessed_eapi)); + if (_imp->eapi_from_suffix || ! guessed->supported()) + return guessed; + + Context ctx("When parsing EAPI from '" + stringify(_imp->fs_location->parse_value()) + "':"); + + std::string eapi_assign(guessed->supported()->ebuild_metadata_variables()->eapi()->name()); + eapi_assign += '='; + + try + { + SafeIFStream eb(_imp->fs_location->parse_value()); + std::string line; + + while (std::getline(eb, line)) + { + std::string::size_type past_indent(line.find_first_not_of(" \t")); + if (std::string::npos == past_indent || line.at(past_indent) == '#') + continue; + + if (line.compare(past_indent, eapi_assign.length(), eapi_assign) != 0) + break; + std::string::size_type value_start(past_indent + eapi_assign.length()); + + char quote('\0'); + if (line.length() > value_start && (line.at(value_start) == '"' || line.at(value_start) == '\'')) + { + quote = line.at(value_start++); + if (line.length() < value_start) + break; + } + + std::string::size_type value_end(line.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_.-", value_start)); + std::string value(line, value_start, std::string::npos == value_end + ? std::string::npos : value_end - value_start); + + if ('\0' != quote && (std::string::npos == value_end || line.at(value_end++) != quote)) + break; + + if (std::string::npos != value_end) + { + std::string::size_type trailing(line.find_first_not_of(" \t", value_end)); + if (std::string::npos != trailing && (trailing == value_end || '#' != line.at(trailing))) + break; + } + + if (value.empty()) + { + auto repo(_imp->environment->fetch_repository(repository_name())); + auto e_repo(std::static_pointer_cast<const ERepository>(repo)); + return EAPIData::get_instance()->eapi_from_string(e_repo->params().eapi_when_unspecified()); + } + return EAPIData::get_instance()->eapi_from_string(value); + } + } + catch (const SafeIFStreamError & e) + { + Log::get_instance()->message("e.ebuild.metadata.eapi_unparsable", ll_warning, lc_context) << e.message(); + return EAPIData::get_instance()->unknown_eapi(); + } + + return guessed; +} + void EbuildID::need_xml_keys_added() const { diff --git a/paludis/repositories/e/ebuild_id.hh b/paludis/repositories/e/ebuild_id.hh index bc9d706a2..255062b58 100644 --- a/paludis/repositories/e/ebuild_id.hh +++ b/paludis/repositories/e/ebuild_id.hh @@ -42,6 +42,7 @@ namespace paludis protected: virtual void need_keys_added() const; void need_non_xml_keys_added() const; + const std::shared_ptr<const EAPI> presource_eapi() const; void need_xml_keys_added() const; virtual void need_masks_added() const; @@ -56,6 +57,7 @@ namespace paludis const RepositoryName &, const FSPath & file, const std::string & guessed_eapi, + const bool eapi_from_suffix, const time_t master_mtime, const std::shared_ptr<const EclassMtimes> & eclass_mtimes); |