aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-09-05 13:53:45 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-09-05 14:10:53 +0100
commitab6ef15c88f168bd5bc75967e62aa76f10066fb6 (patch)
treedb5c8f0b38b2f075932acfc80f99d9f886c748b7
parent8e64395fe44d175b7ce4a468f94062680ea96a1b (diff)
downloadpaludis-ab6ef15c88f168bd5bc75967e62aa76f10066fb6.tar.gz
paludis-ab6ef15c88f168bd5bc75967e62aa76f10066fb6.tar.xz
user specs [.$role]
Fixes: ticket:985
-rw-r--r--doc/configuration/specs.html.part7
-rw-r--r--paludis/user_dep_spec.cc73
-rw-r--r--paludis/user_dep_spec_TEST.cc8
3 files changed, 79 insertions, 9 deletions
diff --git a/doc/configuration/specs.html.part b/doc/configuration/specs.html.part
index 79f75f2..97029e3 100644
--- a/doc/configuration/specs.html.part
+++ b/doc/configuration/specs.html.part
@@ -32,12 +32,15 @@ the following order:</p>
<li><code>[=1.23]</code>: Match a particular version. Any operator described below
can be used. May be extended to ranged dependencies, using either <code>[=1.23|=1.24|=1.25]</code> for an or
dependency or <code>[&gt;=1.2&amp;&lt;2]</code> for an and dependency.</li>
- <li><code>[.key?]</code>: Match only if the specified metadata key exists.</li>
+ <li><code>[.key?]</code>: Match only if the specified metadata key exists. <code>key</code> may be a key's raw
+ name (e.g. <code>DESCRIPTION</code>, <code>DEPEND</code>) or a role prefixed with a dollar sign (e.g.
+ <code>$short_description</code>, <code>$build_dependencies</code>).</li>
<li><code>[.key=value]</code>: Match only if the specified metadata key has a particular exact value. Only works for
simple values, sets and sequences, not spec trees and other complex compound keys. If <code>&lt;</code> is used in
place of <code>=</code>, for numeric values a less-than comparison is used, and for sets, sequences and spec trees,
a match occurs if any member of the set or sequence is equal to the value. Similarly if <code>&gt;</code> is used,
- for numeric values a greater-than comparison is used; it does not match for other types of values.</li>
+ for numeric values a greater-than comparison is used; it does not match for other types of values. The key may
+ be a raw name or a dollar-prefixed role name as above.</li>
</ul>
<p>Repository requirements are in the form <code>to</code>, <code>from-&gt;</code> or <code>::from-&gt;to</code>. The
diff --git a/paludis/user_dep_spec.cc b/paludis/user_dep_spec.cc
index 600f50a..bcee27f 100644
--- a/paludis/user_dep_spec.cc
+++ b/paludis/user_dep_spec.cc
@@ -758,8 +758,61 @@ UserKeyRequirement::requirement_met(const Environment * const, const ChangedChoi
{
Context context("When working out whether '" + stringify(id) + "' matches " + as_raw_string() + ":");
- PackageID::MetadataConstIterator m(id.find_metadata(_imp->key));
- if (m == id.end_metadata())
+ const MetadataKey * key(0);
+
+ if ((! _imp->key.empty()) && (_imp->key.at(0) == '$'))
+ {
+ if (_imp->key == "$behaviours")
+ key = id.behaviours_key().get();
+ else if (_imp->key == "$build_dependencies")
+ key = id.build_dependencies_key().get();
+ else if (_imp->key == "$choices")
+ key = id.choices_key().get();
+ else if (_imp->key == "$contained_in")
+ key = id.contained_in_key().get();
+ else if (_imp->key == "$contains")
+ key = id.contains_key().get();
+ else if (_imp->key == "$contents")
+ key = id.contents_key().get();
+ else if (_imp->key == "$dependencies")
+ key = id.dependencies_key().get();
+ else if (_imp->key == "$fetches")
+ key = id.fetches_key().get();
+ else if (_imp->key == "$from_repositories")
+ key = id.from_repositories_key().get();
+ else if (_imp->key == "$fs_location")
+ key = id.fs_location_key().get();
+ else if (_imp->key == "$homepage")
+ key = id.homepage_key().get();
+ else if (_imp->key == "$installed_time")
+ key = id.installed_time_key().get();
+ else if (_imp->key == "$keywords")
+ key = id.keywords_key().get();
+ else if (_imp->key == "$long_description")
+ key = id.long_description_key().get();
+ else if (_imp->key == "$post_dependencies")
+ key = id.post_dependencies_key().get();
+ else if (_imp->key == "$provide")
+ key = id.provide_key().get();
+ else if (_imp->key == "$run_dependencies")
+ key = id.run_dependencies_key().get();
+ else if (_imp->key == "$short_description")
+ key = id.short_description_key().get();
+ else if (_imp->key == "$slot")
+ key = id.slot_key().get();
+ else if (_imp->key == "$suggested_dependencies")
+ key = id.suggested_dependencies_key().get();
+ else if (_imp->key == "$virtual_for")
+ key = id.virtual_for_key().get();
+ }
+ else
+ {
+ PackageID::MetadataConstIterator m(id.find_metadata(_imp->key));
+ if (m != id.end_metadata())
+ key = m->get();
+ }
+
+ if (! key)
return std::make_pair(false, as_human_string());
if (_imp->op == '?')
@@ -767,23 +820,29 @@ UserKeyRequirement::requirement_met(const Environment * const, const ChangedChoi
else
{
KeyComparator c(_imp->value, _imp->op);
- return std::make_pair((*m)->accept_returning<bool>(c), as_human_string());
+ return std::make_pair(key->accept_returning<bool>(c), as_human_string());
}
}
const std::string
UserKeyRequirement::as_human_string() const
{
+ std::string key_str;
+ if ((! _imp->key.empty()) && (_imp->key.at(0) == '$'))
+ key_str = "with role '" + _imp->key.substr(1) + "'";
+ else
+ key_str = "'" + _imp->key + "'";
+
switch (_imp->op)
{
case '=':
- return "Key '" + _imp->key + "' has simple string value '" + _imp->value + "'";
+ return "Key " + key_str + " has simple string value '" + _imp->value + "'";
case '<':
- return "Key '" + _imp->key + "' contains or is less than '" + _imp->value + "'";
+ return "Key " + key_str + " contains or is less than '" + _imp->value + "'";
case '>':
- return "Key '" + _imp->key + "' is greater than '" + _imp->value + "'";
+ return "Key " + key_str + " is greater than '" + _imp->value + "'";
case '?':
- return "Key '" + _imp->key + "' exists";
+ return "Key " + key_str + " exists";
}
throw InternalError(PALUDIS_HERE, "unknown op");
diff --git a/paludis/user_dep_spec_TEST.cc b/paludis/user_dep_spec_TEST.cc
index d1950af..033c49e 100644
--- a/paludis/user_dep_spec_TEST.cc
+++ b/paludis/user_dep_spec_TEST.cc
@@ -230,6 +230,9 @@ namespace test_cases
PackageDepSpec q(parse_user_package_dep_spec("foo/bar[.foo?]", &env, { }));
check_spec(q, "foo/bar", "", "", "", "", "", "", "", "[.foo?]");
+
+ PackageDepSpec r(parse_user_package_dep_spec("foo/bar[.$short_description=value]", &env, { }));
+ check_spec(r, "foo/bar", "", "", "", "", "", "", "", "[.$short_description=value]");
}
} test_user_package_dep_spec;
@@ -479,6 +482,11 @@ namespace test_cases
PackageDepSpec n(parse_user_package_dep_spec("cat/pkg1[.SPOON?]", &env, { }));
TEST_CHECK(! match_package(env, n, *pkg1, { }));
+
+ PackageDepSpec o(parse_user_package_dep_spec("cat/pkg1[.$keywords<~a]", &env, { }));
+ TEST_CHECK(match_package(env, o, *pkg1, { }));
+ TEST_CHECK(match_package(env, o, *pkg2, { }));
+ TEST_CHECK(! match_package(env, o, *pkg3, { }));
}
} test_user_package_dep_spec_user_key_req;
}