diff options
author | 2008-04-22 05:19:26 +0000 | |
---|---|---|
committer | 2008-04-22 05:19:26 +0000 | |
commit | f6739689f4a4971ee069cd7d9d0eb226e80eb10c (patch) | |
tree | 4ed204a50d851de501895d340bd54de5788411e3 | |
parent | f4e46e016ae53de0699aff46f961e254c9fbafc5 (diff) | |
download | paludis-f6739689f4a4971ee069cd7d9d0eb226e80eb10c.tar.gz paludis-f6739689f4a4971ee069cd7d9d0eb226e80eb10c.tar.xz |
Implement foo* sets. Fixes: ticket:561
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | doc/configuration/sets.html.part.in | 5 | ||||
-rw-r--r-- | paludis/environments/paludis/paludis_environment.cc | 26 | ||||
-rw-r--r-- | paludis/environments/paludis/world.cc | 3 | ||||
-rw-r--r-- | paludis/environments/portage/portage_environment.cc | 3 | ||||
-rw-r--r-- | paludis/name.cc | 7 | ||||
-rw-r--r-- | paludis/name_TEST.cc | 24 | ||||
-rw-r--r-- | paludis/repositories/e/e_installed_repository.cc | 1 | ||||
-rw-r--r-- | paludis/repositories/e/e_repository_sets.cc | 19 | ||||
-rw-r--r-- | paludis/set_file.cc | 35 | ||||
-rw-r--r-- | paludis/set_file.hh | 12 | ||||
-rw-r--r-- | paludis/set_file.se | 15 | ||||
-rw-r--r-- | paludis/set_file.sr | 1 | ||||
-rw-r--r-- | paludis/set_file_TEST.cc | 41 | ||||
-rwxr-xr-x | paludis/set_file_TEST_setup.sh | 8 | ||||
-rw-r--r-- | ruby/environment_TEST.rb | 6 |
16 files changed, 182 insertions, 27 deletions
@@ -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 dadcecd6b..8561f4a17 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 6000c02f1..cd26154df 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 4d71c6897..ed4ecb9a8 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 c6f2ecc71..7fa3bf645 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 f3f936d14..1aaa50ef2 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 4de4856c0..cbd0c97a7 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 454098e41..eb8bfc2dd 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 d92996c25..9e7f0f154 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 1a8a464ce..339b90f93 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 08c2ae931..9a34a6a02 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 88d0ad33c..05da791be 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 13184521c..bdcc464a0 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 9bbb7b352..5eace1c5f 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 aa86fc0e4..5f61f97c5 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 37bdf3617..211015d93 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 |