aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-04-22 05:19:26 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-04-22 05:19:26 +0000
commitf6739689f4a4971ee069cd7d9d0eb226e80eb10c (patch)
tree4ed204a50d851de501895d340bd54de5788411e3
parentf4e46e016ae53de0699aff46f961e254c9fbafc5 (diff)
downloadpaludis-f6739689f4a4971ee069cd7d9d0eb226e80eb10c.tar.gz
paludis-f6739689f4a4971ee069cd7d9d0eb226e80eb10c.tar.xz
Implement foo* sets. Fixes: ticket:561
-rw-r--r--NEWS3
-rw-r--r--doc/configuration/sets.html.part.in5
-rw-r--r--paludis/environments/paludis/paludis_environment.cc26
-rw-r--r--paludis/environments/paludis/world.cc3
-rw-r--r--paludis/environments/portage/portage_environment.cc3
-rw-r--r--paludis/name.cc7
-rw-r--r--paludis/name_TEST.cc24
-rw-r--r--paludis/repositories/e/e_installed_repository.cc1
-rw-r--r--paludis/repositories/e/e_repository_sets.cc19
-rw-r--r--paludis/set_file.cc35
-rw-r--r--paludis/set_file.hh12
-rw-r--r--paludis/set_file.se15
-rw-r--r--paludis/set_file.sr1
-rw-r--r--paludis/set_file_TEST.cc41
-rwxr-xr-xpaludis/set_file_TEST_setup.sh8
-rw-r--r--ruby/environment_TEST.rb6
16 files changed, 182 insertions, 27 deletions
diff --git a/NEWS b/NEWS
index 482e1c2..01ec997 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,9 @@ trunk/:
should be added manually if appropriate. The special "ununused" set no
longer exists.
+ * If 'foo' is a user defined set, we automatically create 'foo*' which is
+ like 'foo' but with all operators treated as '*' recursively.
+
0.26.0_pre2:
* paludis now supports ${root} in environment.conf. This can be
used when defining the "world" key, so that the configuration
diff --git a/doc/configuration/sets.html.part.in b/doc/configuration/sets.html.part.in
index dadcecd..8561f4a 100644
--- a/doc/configuration/sets.html.part.in
+++ b/doc/configuration/sets.html.part.in
@@ -53,3 +53,8 @@ specification or, for some operators, a set name. Permitted operators are:</p>
<dd>Like <code>?</code>, but considers the slot part of the specification (if any) in addition to the name part.</dd>
</dl>
+<p>If the set <code>foo</code> exists and is not a builtin set, the special set <code>foo*</code> is automatically
+generated by Paludis. The <code>foo*</code> set is like the <code>foo</code> set, except that it behaves as if every
+operator is a <code>*</code>. In addition, any set names inside that set are treated as if they were
+<code>setname*</code>, so that the operator behaviour override is recursive.</p>
+
diff --git a/paludis/environments/paludis/paludis_environment.cc b/paludis/environments/paludis/paludis_environment.cc
index 6000c02..cd26154 100644
--- a/paludis/environments/paludis/paludis_environment.cc
+++ b/paludis/environments/paludis/paludis_environment.cc
@@ -341,48 +341,52 @@ PaludisEnvironment::syncers_dirs() const
}
tr1::shared_ptr<SetSpecTree::ConstItem>
-PaludisEnvironment::local_set(const SetName & s) const
+PaludisEnvironment::local_set(const SetName & ss) const
{
using namespace tr1::placeholders;
- Context context("When looking for package set '" + stringify(s) + "' in paludis environment:");
+ Context context("When looking for package set '" + stringify(ss) + "' in paludis environment:");
Lock l(_imp->sets_mutex);
- std::map<SetName, tr1::shared_ptr<SetSpecTree::ConstItem> >::const_iterator i(_imp->sets.find(s));
+ std::map<SetName, tr1::shared_ptr<SetSpecTree::ConstItem> >::const_iterator i(_imp->sets.find(ss));
if (i != _imp->sets.end())
return i->second;
+ std::pair<SetName, SetFileSetOperatorMode> s(find_base_set_name_and_suffix_mode(ss));
+
FSEntry dir(FSEntry(_imp->config->config_dir()) / "sets");
- tr1::shared_ptr<GeneralSetDepTag> tag(new GeneralSetDepTag(s, stringify(s) + ".conf"));
+ tr1::shared_ptr<GeneralSetDepTag> tag(new GeneralSetDepTag(ss, stringify(s.first) + ".conf"));
- if ((dir / (stringify(s) + ".bash")).exists())
+ if ((dir / (stringify(s.first) + ".bash")).exists())
{
SetFile f(SetFileParams::create()
- .file_name(dir / (stringify(s) + ".bash"))
+ .file_name(dir / (stringify(s.first) + ".bash"))
.type(sft_paludis_bash)
.parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions() + updso_allow_wildcards))
.tag(tag)
+ .set_operator_mode(s.second)
.environment(this));
- _imp->sets.insert(std::make_pair(s, f.contents()));
+ _imp->sets.insert(std::make_pair(ss, f.contents()));
return f.contents();
}
- else if ((dir / (stringify(s) + ".conf")).exists())
+ else if ((dir / (stringify(s.first) + ".conf")).exists())
{
SetFile f(SetFileParams::create()
- .file_name(dir / (stringify(s) + ".conf"))
+ .file_name(dir / (stringify(s.first) + ".conf"))
.type(sft_paludis_conf)
.parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions() + updso_allow_wildcards))
.tag(tag)
+ .set_operator_mode(s.second)
.environment(this));
- _imp->sets.insert(std::make_pair(s, f.contents()));
+ _imp->sets.insert(std::make_pair(ss, f.contents()));
return f.contents();
}
else
{
- _imp->sets.insert(std::make_pair(s, tr1::shared_ptr<SetSpecTree::ConstItem>()));
+ _imp->sets.insert(std::make_pair(ss, tr1::shared_ptr<SetSpecTree::ConstItem>()));
return tr1::shared_ptr<SetSpecTree::ConstItem>();
}
}
diff --git a/paludis/environments/paludis/world.cc b/paludis/environments/paludis/world.cc
index 4d71c68..ed4ecb9 100644
--- a/paludis/environments/paludis/world.cc
+++ b/paludis/environments/paludis/world.cc
@@ -116,6 +116,7 @@ World::_add_string_to_world(const std::string & n) const
.type(sft_simple)
.parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions()))
.tag(tr1::shared_ptr<DepTag>())
+ .set_operator_mode(sfsmo_natural)
.environment(_imp->env));
world.add(n);
world.rewrite();
@@ -144,6 +145,7 @@ World::_remove_string_from_world(const std::string & n) const
.type(sft_simple)
.parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions()))
.tag(tr1::shared_ptr<DepTag>())
+ .set_operator_mode(sfsmo_natural)
.environment(_imp->env));
world.remove(n);
@@ -167,6 +169,7 @@ World::world_set() const
.type(sft_simple)
.parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions()))
.tag(tag)
+ .set_operator_mode(sfsmo_natural)
.environment(_imp->env));
return world.contents();
}
diff --git a/paludis/environments/portage/portage_environment.cc b/paludis/environments/portage/portage_environment.cc
index c6f2ecc..7fa3bf6 100644
--- a/paludis/environments/portage/portage_environment.cc
+++ b/paludis/environments/portage/portage_environment.cc
@@ -795,6 +795,7 @@ PortageEnvironment::_add_string_to_world(const std::string & s) const
.type(sft_simple)
.parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions()))
.tag(tr1::shared_ptr<DepTag>())
+ .set_operator_mode(sfsmo_natural)
.environment(this));
world.add(s);
world.rewrite();
@@ -816,6 +817,7 @@ PortageEnvironment::_remove_string_from_world(const std::string & s) const
.type(sft_simple)
.parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions()))
.tag(tr1::shared_ptr<DepTag>())
+ .set_operator_mode(sfsmo_natural)
.environment(this));
world.remove(s);
@@ -841,6 +843,7 @@ PortageEnvironment::world_set() const
.type(sft_simple)
.parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions()))
.tag(tag)
+ .set_operator_mode(sfsmo_natural)
.environment(this));
return world.contents();
}
diff --git a/paludis/name.cc b/paludis/name.cc
index f3f936d..1aaa50e 100644
--- a/paludis/name.cc
+++ b/paludis/name.cc
@@ -388,6 +388,13 @@ SetNameValidator::validate(const std::string & s)
if (s.empty())
break;
+ if (s.length() > 1 && '*' == s[s.length() - 1] && '*' != s[s.length() - 2])
+ {
+ Context c("When validating set name '" + s + "':");
+ validate(s.substr(0, s.length() - 1));
+ return;
+ }
+
if ('-' == s[0] || '.' == s[0])
break;
diff --git a/paludis/name_TEST.cc b/paludis/name_TEST.cc
index 4de4856..cbd0c97 100644
--- a/paludis/name_TEST.cc
+++ b/paludis/name_TEST.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2005, 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
@@ -343,7 +343,27 @@ namespace test_cases
}
} test_keyword_name_validation;
+ struct SetNameValidationTest : public TestCase
+ {
+ SetNameValidationTest() : TestCase("validation") { }
-
+ void run()
+ {
+ SetName k("set0_-");
+ SetName k1("set0_-");
+ SetName k2("set0*");
+ TEST_CHECK_THROWS(k = SetName(""), NameError);
+ TEST_CHECK_THROWS(k = SetName("!!!"), NameError);
+ TEST_CHECK_THROWS(k = SetName("~"), NameError);
+ TEST_CHECK_THROWS(k = SetName("-"), NameError);
+ TEST_CHECK_THROWS(k = SetName("f?oo"), NameError);
+ TEST_CHECK_THROWS(k = SetName("*"), NameError);
+ TEST_CHECK_THROWS(k = SetName("?"), NameError);
+ TEST_CHECK_THROWS(k = SetName("*set"), NameError);
+ TEST_CHECK_THROWS(k = SetName("set**"), NameError);
+ TEST_CHECK_THROWS(k = SetName("set*?"), NameError);
+ TEST_CHECK_THROWS(k = SetName("set?"), NameError);
+ }
+ } test_set_name_validator;
}
diff --git a/paludis/repositories/e/e_installed_repository.cc b/paludis/repositories/e/e_installed_repository.cc
index 454098e..eb8bfc2 100644
--- a/paludis/repositories/e/e_installed_repository.cc
+++ b/paludis/repositories/e/e_installed_repository.cc
@@ -253,6 +253,7 @@ EInstalledRepository::package_set(const SetName & s) const
.type(sft_simple)
.parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions()))
.tag(tag)
+ .set_operator_mode(sfsmo_natural)
.environment(_imp->params.environment));
return world.contents();
}
diff --git a/paludis/repositories/e/e_repository_sets.cc b/paludis/repositories/e/e_repository_sets.cc
index d92996c..9e7f0f1 100644
--- a/paludis/repositories/e/e_repository_sets.cc
+++ b/paludis/repositories/e/e_repository_sets.cc
@@ -90,28 +90,31 @@ ERepositorySets::~ERepositorySets()
}
tr1::shared_ptr<SetSpecTree::ConstItem>
-ERepositorySets::package_set(const SetName & s) const
+ERepositorySets::package_set(const SetName & ss) const
{
using namespace tr1::placeholders;
- if ("system" == s.data())
+ std::pair<SetName, SetFileSetOperatorMode> s(find_base_set_name_and_suffix_mode(ss));
+
+ if ("system" == s.first.data())
throw InternalError(PALUDIS_HERE, "system set should've been handled by ERepository");
- else if ("security" == s.data())
+ else if ("security" == s.first.data())
return security_set(false);
- else if ("insecurity" == s.data())
+ else if ("insecurity" == s.first.data())
return security_set(true);
- else if ((_imp->params.setsdir / (stringify(s) + ".conf")).exists())
+ else if ((_imp->params.setsdir / (stringify(s.first) + ".conf")).exists())
{
- tr1::shared_ptr<GeneralSetDepTag> tag(new GeneralSetDepTag(s, stringify(_imp->e_repository->name())));
+ tr1::shared_ptr<GeneralSetDepTag> tag(new GeneralSetDepTag(ss, stringify(_imp->e_repository->name())));
- FSEntry ff(_imp->params.setsdir / (stringify(s) + ".conf"));
- Context context("When loading package set '" + stringify(s) + "' from '" + stringify(ff) + "':");
+ FSEntry ff(_imp->params.setsdir / (stringify(s.first) + ".conf"));
+ Context context("When loading package set '" + stringify(s.first) + "' from '" + stringify(ff) + "':");
SetFile f(SetFileParams::create()
.file_name(ff)
.environment(_imp->environment)
.type(sft_paludis_conf)
.parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions()))
+ .set_operator_mode(s.second)
.tag(tag));
return f.contents();
diff --git a/paludis/set_file.cc b/paludis/set_file.cc
index 1a8a464..339b90f 100644
--- a/paludis/set_file.cc
+++ b/paludis/set_file.cc
@@ -188,11 +188,31 @@ namespace
tokens.insert(tokens.begin(), "*");
}
- if ("*" == tokens.at(0))
+ if ("*" == tokens.at(0) || ((sfsmo_star == params.set_operator_mode) &&
+ ("?" == tokens.at(0) || "?:" == tokens.at(0))))
{
if (std::string::npos == tokens.at(1).find('/'))
{
- tr1::shared_ptr<NamedSetDepSpec> spec(new NamedSetDepSpec(SetName(tokens.at(1))));
+ tr1::shared_ptr<NamedSetDepSpec> spec;
+ switch (params.set_operator_mode)
+ {
+ case sfsmo_natural:
+ spec.reset(new NamedSetDepSpec(SetName(tokens.at(1))));
+ break;
+
+ case sfsmo_star:
+ {
+ std::pair<SetName, SetFileSetOperatorMode> s(find_base_set_name_and_suffix_mode(SetName(tokens.at(1))));
+ spec.reset(new NamedSetDepSpec(SetName(stringify(s.first) + "*")));
+ }
+ break;
+
+ case last_sfsmo:
+ break;
+ }
+ if (! spec)
+ throw InternalError(PALUDIS_HERE, "Bad params.set_name_suffix");
+
result->add(tr1::shared_ptr<TreeLeaf<SetSpecTree, NamedSetDepSpec> >(
new TreeLeaf<SetSpecTree, NamedSetDepSpec>(spec)));
}
@@ -570,3 +590,14 @@ SetFile::remove(const std::string & p)
return _imp->handler->remove(p);
}
+std::pair<SetName, SetFileSetOperatorMode>
+paludis::find_base_set_name_and_suffix_mode(const SetName & s)
+{
+ Context context("When working out whether '" + stringify(s) + "' has operators:");
+ std::string ss(stringify(s));
+ if (ss.length() >= 2 && '*' == ss[ss.length() - 1])
+ return std::make_pair(SetName(ss.substr(0, ss.length() - 1)), sfsmo_star);
+ else
+ return std::make_pair(s, sfsmo_natural);
+}
+
diff --git a/paludis/set_file.hh b/paludis/set_file.hh
index 08c2ae9..9a34a6a 100644
--- a/paludis/set_file.hh
+++ b/paludis/set_file.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 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
@@ -119,6 +119,16 @@ namespace paludis
*/
void remove(const std::string &);
};
+
+ /**
+ * Split a SetName into a SetName and a SetFileSetOperatorMode.
+ *
+ * \see SetName
+ * \ingroup g_repository
+ * \since 0.26
+ */
+ std::pair<SetName, SetFileSetOperatorMode> find_base_set_name_and_suffix_mode(const SetName &)
+ PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
}
#endif
diff --git a/paludis/set_file.se b/paludis/set_file.se
index 88d0ad3..05da791 100644
--- a/paludis/set_file.se
+++ b/paludis/set_file.se
@@ -19,5 +19,20 @@ make_enum_SetFileType()
END
}
+make_enum_SetFileSetOperatorMode()
+{
+ prefix sfsmo
+
+ key sfsmo_natural "Do not change operators"
+ key sfsmo_star "Change operators to * and make set names end in *"
+ doxygen_comment << "END"
+ /**
+ * Whether to change operators and set name suffixes.
+ *
+ * \see SetFile
+ * \ingroup g_repository
+ */
+END
+}
diff --git a/paludis/set_file.sr b/paludis/set_file.sr
index 1318452..bdcc464 100644
--- a/paludis/set_file.sr
+++ b/paludis/set_file.sr
@@ -7,6 +7,7 @@ make_class_SetFileParams()
key parser "tr1::function<PackageDepSpec (const std::string &)>"
key tag "tr1::shared_ptr<const DepTag>"
key environment "const Environment *"
+ key set_operator_mode SetFileSetOperatorMode
allow_named_args
diff --git a/paludis/set_file_TEST.cc b/paludis/set_file_TEST.cc
index 9bbb7b3..5eace1c 100644
--- a/paludis/set_file_TEST.cc
+++ b/paludis/set_file_TEST.cc
@@ -75,6 +75,7 @@ namespace test_cases
.type(sft_simple)
.parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions()))
.tag(tr1::shared_ptr<DepTag>())
+ .set_operator_mode(sfsmo_natural)
.environment(0));
{
@@ -138,6 +139,7 @@ namespace test_cases
.type(sft_paludis_conf)
.parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions()))
.tag(tr1::shared_ptr<DepTag>())
+ .set_operator_mode(sfsmo_natural)
.environment(0));
{
@@ -190,5 +192,44 @@ namespace test_cases
return false;
}
} test_paludis_conf;
+
+ struct OverrideTest : TestCase
+ {
+ OverrideTest() : TestCase("operator overrides") { }
+
+ void run()
+ {
+ using namespace tr1::placeholders;
+
+ SetFile f(SetFileParams::create()
+ .file_name(FSEntry("set_file_TEST_dir/override"))
+ .type(sft_paludis_conf)
+ .parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions()))
+ .tag(tr1::shared_ptr<DepTag>())
+ .set_operator_mode(sfsmo_natural)
+ .environment(0));
+
+ {
+ SetSpecStringifier p;
+ f.contents()->accept(p);
+ TEST_CHECK_STRINGIFY_EQUAL(p.s.str(), "( >=bar/bar-1.23 set set2* ) ");
+ }
+
+ SetFile fstar(SetFileParams::create()
+ .file_name(FSEntry("set_file_TEST_dir/override"))
+ .type(sft_paludis_conf)
+ .parser(tr1::bind(&parse_user_package_dep_spec, _1, UserPackageDepSpecOptions()))
+ .tag(tr1::shared_ptr<DepTag>())
+ .set_operator_mode(sfsmo_star)
+ .environment(0));
+
+ {
+ SetSpecStringifier p;
+ fstar.contents()->accept(p);
+ TEST_CHECK_STRINGIFY_EQUAL(p.s.str(), "( foo/foo >=bar/bar-1.23 >=baz/baz-1.23 set* set2* ) ");
+ }
+
+ }
+ } test_overrides;
}
diff --git a/paludis/set_file_TEST_setup.sh b/paludis/set_file_TEST_setup.sh
index aa86fc0..5f61f97 100755
--- a/paludis/set_file_TEST_setup.sh
+++ b/paludis/set_file_TEST_setup.sh
@@ -25,3 +25,11 @@ cat <<"END" > paludisconf1
# the end
END
+cat <<"END" > override
+? foo/foo
+* >=bar/bar-1.23
+? >=baz/baz-1.23
+* set
+* set2*
+END
+
diff --git a/ruby/environment_TEST.rb b/ruby/environment_TEST.rb
index 37bdf36..211015d 100644
--- a/ruby/environment_TEST.rb
+++ b/ruby/environment_TEST.rb
@@ -2,7 +2,7 @@
# vim: set sw=4 sts=4 et tw=80 :
#
-# Copyright (c) 2006, 2007 Ciaran McCreesh
+# Copyright (c) 2006, 2007, 2008 Ciaran McCreesh
# Copyright (c) 2007 Richard Brown
#
# This file is part of the Paludis package manager. Paludis is free software;
@@ -285,7 +285,7 @@ module Paludis
def test_package_set_error
assert_raise SetNameError do
- env.set('broken*')
+ env.set('broken#')
end
end
end
@@ -301,7 +301,7 @@ module Paludis
def test_package_set_error
assert_raise SetNameError do
- env.set('broken*')
+ env.set('broken#')
end
end
end