aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-09-05 13:34:55 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-09-05 14:10:52 +0100
commit8e64395fe44d175b7ce4a468f94062680ea96a1b (patch)
treebe8e56ac58a09631a01d1849d5e7dc66ee6d648a
parent4d0a770757e430cb2e972ea8aefd09d3294c2ce3 (diff)
downloadpaludis-8e64395fe44d175b7ce4a468f94062680ea96a1b.tar.gz
paludis-8e64395fe44d175b7ce4a468f94062680ea96a1b.tar.xz
user specs [.key?]
Fixes: ticket:984
-rw-r--r--doc/configuration/specs.html.part1
-rw-r--r--paludis/user_dep_spec.cc18
-rw-r--r--paludis/user_dep_spec_TEST.cc11
3 files changed, 26 insertions, 4 deletions
diff --git a/doc/configuration/specs.html.part b/doc/configuration/specs.html.part
index 9903a35..79f75f2 100644
--- a/doc/configuration/specs.html.part
+++ b/doc/configuration/specs.html.part
@@ -32,6 +32,7 @@ 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=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,
diff --git a/paludis/user_dep_spec.cc b/paludis/user_dep_spec.cc
index ed516e0..600f50a 100644
--- a/paludis/user_dep_spec.cc
+++ b/paludis/user_dep_spec.cc
@@ -356,13 +356,16 @@ namespace paludis
Imp(const std::string & s)
{
- std::string::size_type p(s.find_first_of("=<>"));
+ std::string::size_type p(s.find_first_of("=<>?"));
if (std::string::npos == p)
- throw PackageDepSpecError("Expected an =, a < or a > inside '[." + s + "]'");
+ throw PackageDepSpecError("Expected an =, a <, a > or a ? inside '[." + s + "]'");
key = s.substr(0, p);
value = s.substr(p + 1);
op = s.at(p);
+
+ if (op == '?' && ! value.empty())
+ throw PackageDepSpecError("Operator '?' takes no value inside '[." + s + "]'");
}
};
}
@@ -759,8 +762,13 @@ UserKeyRequirement::requirement_met(const Environment * const, const ChangedChoi
if (m == id.end_metadata())
return std::make_pair(false, as_human_string());
- KeyComparator c(_imp->value, _imp->op);
- return std::make_pair((*m)->accept_returning<bool>(c), as_human_string());
+ if (_imp->op == '?')
+ return std::make_pair(true, as_human_string());
+ else
+ {
+ KeyComparator c(_imp->value, _imp->op);
+ return std::make_pair((*m)->accept_returning<bool>(c), as_human_string());
+ }
}
const std::string
@@ -774,6 +782,8 @@ UserKeyRequirement::as_human_string() const
return "Key '" + _imp->key + "' contains or is less than '" + _imp->value + "'";
case '>':
return "Key '" + _imp->key + "' is greater than '" + _imp->value + "'";
+ case '?':
+ return "Key '" + _imp->key + "' exists";
}
throw InternalError(PALUDIS_HERE, "unknown op");
diff --git a/paludis/user_dep_spec_TEST.cc b/paludis/user_dep_spec_TEST.cc
index 5d02404..d1950af 100644
--- a/paludis/user_dep_spec_TEST.cc
+++ b/paludis/user_dep_spec_TEST.cc
@@ -225,6 +225,11 @@ namespace test_cases
PackageDepSpec p(parse_user_package_dep_spec("foo/bar[.key=value]", &env, { }));
check_spec(p, "foo/bar", "", "", "", "", "", "", "", "[.key=value]");
+
+ TEST_CHECK_THROWS(parse_user_package_dep_spec("=foo/bar[.foo?q]", &env, { }), PackageDepSpecError);
+
+ PackageDepSpec q(parse_user_package_dep_spec("foo/bar[.foo?]", &env, { }));
+ check_spec(q, "foo/bar", "", "", "", "", "", "", "", "[.foo?]");
}
} test_user_package_dep_spec;
@@ -468,6 +473,12 @@ namespace test_cases
PackageDepSpec l(parse_user_package_dep_spec("cat/pkg1[.HITCHHIKER>41]", &env, { }));
TEST_CHECK(match_package(env, l, *pkg1, { }));
+
+ PackageDepSpec m(parse_user_package_dep_spec("cat/pkg1[.HITCHHIKER?]", &env, { }));
+ TEST_CHECK(match_package(env, m, *pkg1, { }));
+
+ PackageDepSpec n(parse_user_package_dep_spec("cat/pkg1[.SPOON?]", &env, { }));
+ TEST_CHECK(! match_package(env, n, *pkg1, { }));
}
} test_user_package_dep_spec_user_key_req;
}