aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar David Leverton <levertond@googlemail.com> 2012-05-14 00:42:31 +0100
committerAvatar David Leverton <levertond@googlemail.com> 2012-05-14 00:42:31 +0100
commit1c6c441208ab6c63c11e79dcd7c2544e605a5766 (patch)
treeb6891ae6b0c8ac13596d9dcdc90a2d994a358b54
parentbac000ad4304bd6045a5814b1bad384988b7a477 (diff)
downloadpaludis-1c6c441208ab6c63c11e79dcd7c2544e605a5766.tar.gz
paludis-1c6c441208ab6c63c11e79dcd7c2544e605a5766.tar.xz
Parse EAPI directly rather than getting it from bash
Gentoo bug #402167. This implementation doesn't allow the parsed EAPI to alter the version parsing rules - some refactoring would be probably be required if that's ever needed.
-rw-r--r--paludis/repositories/e/e_repository.cc2
-rw-r--r--paludis/repositories/e/e_repository_TEST.cc30
-rwxr-xr-xpaludis/repositories/e/e_repository_TEST_setup.sh165
-rw-r--r--paludis/repositories/e/ebuild.cc14
-rw-r--r--paludis/repositories/e/ebuild_id.cc77
-rw-r--r--paludis/repositories/e/ebuild_id.hh2
6 files changed, 281 insertions, 9 deletions
diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc
index 1e4dbac..94a3ebc 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 448fe14..b32bab4 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 fc7eba6..9b24d4a 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 2ee9735..dede6c3 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 ae6ae97..f2dc1ad 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 bc9d706..255062b 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);