diff options
Diffstat (limited to 'paludis')
-rw-r--r-- | paludis/distributions/exherbo/paludis.conf | 1 | ||||
-rw-r--r-- | paludis/distributions/gentoo/paludis.conf | 1 | ||||
-rw-r--r-- | paludis/environments/paludis/Makefile.am | 36 | ||||
-rw-r--r-- | paludis/environments/paludis/extra_distribution_data.cc | 1 | ||||
-rw-r--r-- | paludis/environments/paludis/extra_distribution_data.hh | 2 | ||||
-rw-r--r-- | paludis/environments/paludis/paludis_config.cc | 35 | ||||
-rw-r--r-- | paludis/environments/paludis/paludis_config.hh | 2 | ||||
-rw-r--r-- | paludis/environments/paludis/paludis_environment.cc | 7 | ||||
-rw-r--r-- | paludis/environments/paludis/suggestions_conf.cc | 246 | ||||
-rw-r--r-- | paludis/environments/paludis/suggestions_conf.hh | 67 |
10 files changed, 378 insertions, 20 deletions
diff --git a/paludis/distributions/exherbo/paludis.conf b/paludis/distributions/exherbo/paludis.conf index 4506ae89c..0b0c21aa2 100644 --- a/paludis/distributions/exherbo/paludis.conf +++ b/paludis/distributions/exherbo/paludis.conf @@ -10,5 +10,6 @@ package_mask_filename_part = package_mask package_unmask_filename_part = package_unmask repositories_directory = repositories repository_defaults_filename_part = repository_defaults +suggestions_filename_part = suggestions use_filename_part = options diff --git a/paludis/distributions/gentoo/paludis.conf b/paludis/distributions/gentoo/paludis.conf index db707ed14..2899ea636 100644 --- a/paludis/distributions/gentoo/paludis.conf +++ b/paludis/distributions/gentoo/paludis.conf @@ -10,5 +10,6 @@ package_mask_filename_part = package_mask package_unmask_filename_part = package_unmask repositories_directory = repositories repository_defaults_filename_part = repository_defaults +suggestions_filename_part = suggestions use_filename_part = use diff --git a/paludis/environments/paludis/Makefile.am b/paludis/environments/paludis/Makefile.am index 0c5106e50..0703e1936 100644 --- a/paludis/environments/paludis/Makefile.am +++ b/paludis/environments/paludis/Makefile.am @@ -10,17 +10,18 @@ DEFS= \ -DSHAREDIR=\"$(datarootdir)\" libpaludispaludisenvironment_la_SOURCES = \ - bashable_conf.cc bashable_conf.hh \ - keywords_conf.cc keywords_conf.hh \ - licenses_conf.cc licenses_conf.hh \ - package_mask_conf.cc package_mask_conf.hh \ - use_conf.cc use_conf.hh \ - mirrors_conf.cc mirrors_conf.hh \ - output_conf.cc output_conf.hh \ - world.cc world.hh \ - paludis_config.cc paludis_config.hh \ - paludis_environment.cc paludis_environment.hh \ + bashable_conf.cc bashable_conf.hh \ extra_distribution_data.cc extra_distribution_data.hh \ + keywords_conf.cc keywords_conf.hh \ + licenses_conf.cc licenses_conf.hh \ + mirrors_conf.cc mirrors_conf.hh \ + output_conf.cc output_conf.hh \ + package_mask_conf.cc package_mask_conf.hh \ + paludis_config.cc paludis_config.hh \ + paludis_environment.cc paludis_environment.hh \ + suggestions_conf.cc suggestions_conf.hh \ + use_conf.cc use_conf.hh \ + world.cc world.hh \ registration.cc shareenvpaludisdir = $(datarootdir)/paludis/environments/paludis/ @@ -36,16 +37,17 @@ libenvdir = $(libdir)/paludis/environments noinst_LTLIBRARIES = libpaludispaludisenvironment.la noinst_HEADERS = \ - paludis_config.hh \ - paludis_environment.hh \ - use_conf.hh \ + bashable_conf.hh \ + extra_distribution_data.hh \ keywords_conf.hh \ licenses_conf.hh \ - bashable_conf.hh \ - package_mask_conf.hh \ - world.hh \ mirrors_conf.hh \ - extra_distribution_data.hh + package_mask_conf.hh \ + paludis_config.hh \ + paludis_environment.hh \ + suggestions_conf.hh \ + use_conf.hh \ + world.hh EXTRA_DIST = \ paludis_environment_TEST_setup.sh \ diff --git a/paludis/environments/paludis/extra_distribution_data.cc b/paludis/environments/paludis/extra_distribution_data.cc index 4170948d0..af09445e5 100644 --- a/paludis/environments/paludis/extra_distribution_data.cc +++ b/paludis/environments/paludis/extra_distribution_data.cc @@ -51,6 +51,7 @@ namespace paludis n::package_unmask_filename_part() = k->get("package_unmask_filename_part"), n::repositories_directory() = k->get("repositories_directory"), n::repository_defaults_filename_part() = k->get("repository_defaults_filename_part"), + n::suggestions_filename_part() = k->get("suggestions_filename_part"), n::use_filename_part() = k->get("use_filename_part") )); } diff --git a/paludis/environments/paludis/extra_distribution_data.hh b/paludis/environments/paludis/extra_distribution_data.hh index aa49b8d29..09b05abf3 100644 --- a/paludis/environments/paludis/extra_distribution_data.hh +++ b/paludis/environments/paludis/extra_distribution_data.hh @@ -40,6 +40,7 @@ namespace paludis typedef Name<struct package_unmask_filename_part_name> package_unmask_filename_part; typedef Name<struct repositories_directory_name> repositories_directory; typedef Name<struct repository_defaults_filename_part_name> repository_defaults_filename_part; + typedef Name<struct suggestions_filename_part_name> suggestions_filename_part; typedef Name<struct use_filename_part_name> use_filename_part; } @@ -59,6 +60,7 @@ namespace paludis NamedValue<n::package_unmask_filename_part, std::string> package_unmask_filename_part; NamedValue<n::repositories_directory, std::string> repositories_directory; NamedValue<n::repository_defaults_filename_part, std::string> repository_defaults_filename_part; + NamedValue<n::suggestions_filename_part, std::string> suggestions_filename_part; NamedValue<n::use_filename_part, std::string> use_filename_part; }; diff --git a/paludis/environments/paludis/paludis_config.cc b/paludis/environments/paludis/paludis_config.cc index 3d98e7b02..ac8619ff5 100644 --- a/paludis/environments/paludis/paludis_config.cc +++ b/paludis/environments/paludis/paludis_config.cc @@ -27,6 +27,7 @@ #include <paludis/environments/paludis/output_conf.hh> #include <paludis/environments/paludis/world.hh> #include <paludis/environments/paludis/extra_distribution_data.hh> +#include <paludis/environments/paludis/suggestions_conf.hh> #include <paludis/util/config_file.hh> #include <paludis/util/destringify.hh> @@ -188,6 +189,7 @@ namespace paludis std::shared_ptr<PackageMaskConf> package_unmask_conf; std::shared_ptr<MirrorsConf> mirrors_conf; std::shared_ptr<OutputConf> output_conf; + std::shared_ptr<SuggestionsConf> suggestions_conf; mutable std::shared_ptr<World> world; mutable Mutex reduced_mutex; @@ -220,6 +222,7 @@ namespace paludis package_unmask_conf(std::make_shared<PackageMaskConf>(e)), mirrors_conf(std::make_shared<MirrorsConf>(e)), output_conf(std::make_shared<OutputConf>(e)), + suggestions_conf(std::make_shared<SuggestionsConf>(e)), has_general_conf(false), accept_all_breaks_portage(false), reduced_username(getenv_with_default("PALUDIS_REDUCED_USERNAME", "paludisbuild")), @@ -853,6 +856,32 @@ PaludisConfig::PaludisConfig(PaludisEnvironment * const e, const std::string & s } } + /* suggestions */ + { + std::list<FSPath> files; + files.push_back(_imp->local_config_dir / (dist->suggestions_filename_part() + ".conf")); + files.push_back(_imp->local_config_dir / (dist->suggestions_filename_part() + ".bash")); + if ((_imp->local_config_dir / (dist->suggestions_filename_part() + ".conf.d")).stat().exists()) + { + std::remove_copy_if(FSIterator(_imp->local_config_dir / (dist->suggestions_filename_part() + ".conf.d"), { }), FSIterator(), std::back_inserter(files), + std::bind(std::logical_not<bool>(), std::bind(&is_file_with_extension, _1, ".conf", IsFileWithOptions()))); + std::remove_copy_if(FSIterator(_imp->local_config_dir / (dist->suggestions_filename_part() + ".conf.d"), { }), FSIterator(), std::back_inserter(files), + std::bind(std::logical_not<bool>(), std::bind(&is_file_with_extension, _1, ".bash", IsFileWithOptions()))); + } + + for (std::list<FSPath>::const_iterator file(files.begin()), file_end(files.end()) ; + file != file_end ; ++file) + { + Context local_context("When reading suggestions file '" + stringify(*file) + "':"); + + if (! file->stat().exists()) + continue; + + _imp->suggestions_conf->add(*file); + } + } + + _imp->bashrc_files->push_back(_imp->local_config_dir / dist->bashrc_filename()); } @@ -1111,6 +1140,12 @@ PaludisConfig::mirrors_conf() const return _imp->mirrors_conf; } +std::shared_ptr<const SuggestionsConf> +PaludisConfig::suggestions_conf() const +{ + return _imp->suggestions_conf; +} + std::shared_ptr<const World> PaludisConfig::world() const { diff --git a/paludis/environments/paludis/paludis_config.hh b/paludis/environments/paludis/paludis_config.hh index 210be8ca8..843f6f3f6 100644 --- a/paludis/environments/paludis/paludis_config.hh +++ b/paludis/environments/paludis/paludis_config.hh @@ -50,6 +50,7 @@ namespace paludis struct MirrorsConf; struct OutputConf; struct World; + struct SuggestionsConf; /** * A PaludisConfigError is thrown if a configuration error is encountered @@ -119,6 +120,7 @@ namespace paludis std::shared_ptr<const MirrorsConf> mirrors_conf() const; std::shared_ptr<const World> world() const; std::shared_ptr<const OutputConf> output_conf() const; + std::shared_ptr<const SuggestionsConf> suggestions_conf() const; ///\} diff --git a/paludis/environments/paludis/paludis_environment.cc b/paludis/environments/paludis/paludis_environment.cc index 2e76cc873..ea98e6d2c 100644 --- a/paludis/environments/paludis/paludis_environment.cc +++ b/paludis/environments/paludis/paludis_environment.cc @@ -26,6 +26,7 @@ #include <paludis/environments/paludis/mirrors_conf.hh> #include <paludis/environments/paludis/output_conf.hh> #include <paludis/environments/paludis/world.hh> +#include <paludis/environments/paludis/suggestions_conf.hh> #include <paludis/util/config_file.hh> #include <paludis/hooker.hh> @@ -498,10 +499,10 @@ PaludisEnvironment::known_choice_value_names( Tribool PaludisEnvironment::interest_in_suggestion( - const std::shared_ptr<const PackageID> &, - const PackageDepSpec &) const + const std::shared_ptr<const PackageID> & i, + const PackageDepSpec & s) const { - return indeterminate; + return _imp->config->suggestions_conf()->interest_in_suggestion(i, s); } const std::shared_ptr<OutputManager> diff --git a/paludis/environments/paludis/suggestions_conf.cc b/paludis/environments/paludis/suggestions_conf.cc new file mode 100644 index 000000000..e277dcebc --- /dev/null +++ b/paludis/environments/paludis/suggestions_conf.cc @@ -0,0 +1,246 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 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 + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/environments/paludis/suggestions_conf.hh> +#include <paludis/environments/paludis/paludis_environment.hh> +#include <paludis/environments/paludis/paludis_config.hh> +#include <paludis/environments/paludis/bashable_conf.hh> +#include <paludis/environment.hh> +#include <paludis/name.hh> +#include <paludis/dep_spec.hh> +#include <paludis/spec_tree.hh> +#include <paludis/user_dep_spec.hh> +#include <paludis/match_package.hh> +#include <paludis/util/config_file.hh> +#include <paludis/package_id.hh> +#include <paludis/util/options.hh> +#include <paludis/util/log.hh> +#include <paludis/util/tokeniser.hh> +#include <paludis/util/pimp-impl.hh> +#include <paludis/util/mutex.hh> +#include <paludis/util/wrapped_forward_iterator.hh> +#include <paludis/util/iterator_funcs.hh> +#include <paludis/util/hashes.hh> +#include <paludis/util/make_null_shared_ptr.hh> +#include <unordered_map> +#include <list> +#include <vector> +#include <map> + +using namespace paludis; +using namespace paludis::paludis_environment; + +namespace +{ + struct ValueFlag + { + bool negated; + std::shared_ptr<const QualifiedPackageName> name; + + ValueFlag(const std::string & s) : + negated(false) + { + std::string s_fixed(s); + + if ((! s_fixed.empty()) && ('-' == s_fixed.at(0))) + { + s_fixed.erase(0, 1); + negated = true; + } + + if (s_fixed.empty()) + throw PaludisConfigError("Empty value flag '" + s + "'"); + + if (s_fixed != "*/*") + name = std::make_shared<QualifiedPackageName>(s_fixed); + } + }; +} + +typedef std::list<ValueFlag> ValuesList; +typedef std::map<std::shared_ptr<const PackageDepSpec>, ValuesList> PDSToValuesList; +typedef std::pair<std::shared_ptr<const SetSpecTree>, ValuesList> SetNameEntry; + +typedef std::unordered_map<QualifiedPackageName, PDSToValuesList, Hash<QualifiedPackageName> > SpecificMap; +typedef PDSToValuesList UnspecificMap; +typedef std::unordered_map<SetName, SetNameEntry, Hash<SetName> > NamedSetMap; + +namespace paludis +{ + template<> + struct Imp<SuggestionsConf> + { + const PaludisEnvironment * const env; + + SpecificMap qualified; + UnspecificMap unqualified; + mutable NamedSetMap set; + mutable Mutex set_mutex; + + Imp(const PaludisEnvironment * const e) : + env(e) + { + } + }; +} + +SuggestionsConf::SuggestionsConf(const PaludisEnvironment * const e) : + Pimp<SuggestionsConf>(e) +{ +} + +SuggestionsConf::~SuggestionsConf() +{ +} + +void +SuggestionsConf::add(const FSPath & filename) +{ + Context context("When adding source '" + stringify(filename) + "' as a suggestions file:"); + + std::shared_ptr<LineConfigFile> f(make_bashable_conf(filename, { })); + if (! f) + return; + + for (LineConfigFile::ConstIterator line(f->begin()), line_end(f->end()) ; + line != line_end ; ++line) + { + std::vector<std::string> tokens; + tokenise_whitespace_quoted(*line, std::back_inserter(tokens)); + + if (tokens.size() < 2) + continue; + + try + { + std::shared_ptr<PackageDepSpec> d(std::make_shared<PackageDepSpec>(parse_user_package_dep_spec( + tokens.at(0), _imp->env, + { updso_allow_wildcards, updso_no_disambiguation, updso_throw_if_set }))); + if (d->package_ptr()) + { + ValuesList & k(_imp->qualified[*d->package_ptr()][d]); + for (std::vector<std::string>::const_iterator t(next(tokens.begin())), t_end(tokens.end()) ; + t != t_end ; ++t) + k.push_back(ValueFlag(*t)); + } + else + { + ValuesList & k(_imp->unqualified[d]); + for (std::vector<std::string>::const_iterator t(next(tokens.begin())), t_end(tokens.end()) ; + t != t_end ; ++t) + k.push_back(ValueFlag(*t)); + } + } + catch (const GotASetNotAPackageDepSpec &) + { + NamedSetMap::iterator i(_imp->set.insert(std::make_pair(SetName(tokens.at(0)), std::make_pair( + make_null_shared_ptr(), ValuesList()))).first); + + for (std::vector<std::string>::const_iterator t(next(tokens.begin())), t_end(tokens.end()) ; + t != t_end ; ++t) + i->second.second.push_back(ValueFlag(*t)); + } + } +} + +Tribool +SuggestionsConf::interest_in_suggestion( + const std::shared_ptr<const PackageID> & from_id, + const PackageDepSpec & spec) const +{ + /* highest priority: specific */ + { + SpecificMap::const_iterator i(_imp->qualified.find(from_id->name())); + if (i != _imp->qualified.end()) + { + for (PDSToValuesList::const_iterator j(i->second.begin()), j_end(i->second.end()) ; + j != j_end ; ++j) + { + if (! match_package(*_imp->env, *j->first, *from_id, { })) + continue; + + for (ValuesList::const_iterator l(j->second.begin()), l_end(j->second.end()) ; + l != l_end ; ++l) + { + if (! l->name) + return l->negated ? false : true; + + if (*l->name == *spec.package_ptr()) + return l->negated ? false : true; + } + } + } + } + + /* next: named sets */ + { + Lock lock(_imp->set_mutex); + for (NamedSetMap::iterator i(_imp->set.begin()), i_end(_imp->set.end()) ; + i != i_end ; ++i) + { + if (! i->second.first) + { + i->second.first = _imp->env->set(i->first); + if (! i->second.first) + { + Log::get_instance()->message("paludis_environment.suggestions_conf.unknown_set", ll_warning, lc_no_context) << "Set name '" + << i->first << "' does not exist"; + i->second.first = std::make_shared<SetSpecTree>(std::make_shared<AllDepSpec>()); + } + } + + if (! match_package_in_set(*_imp->env, *i->second.first, *from_id, { })) + continue; + + for (ValuesList::const_iterator l(i->second.second.begin()), l_end(i->second.second.end()) ; + l != l_end ; ++l) + { + if (! l->name) + return l->negated ? false : true; + + if (*l->name == *spec.package_ptr()) + return l->negated ? false : true; + } + } + } + + + /* last: unspecific */ + for (PDSToValuesList::const_iterator j(_imp->unqualified.begin()), j_end(_imp->unqualified.end()) ; + j != j_end ; ++j) + { + if (! match_package(*_imp->env, *j->first, *from_id, { })) + continue; + + for (ValuesList::const_iterator l(j->second.begin()), l_end(j->second.end()) ; + l != l_end ; ++l) + { + if (! l->name) + return l->negated ? false : true; + + if (*l->name == *spec.package_ptr()) + return l->negated ? false : true; + } + } + + return indeterminate; +} + +template class Pimp<SuggestionsConf>; + diff --git a/paludis/environments/paludis/suggestions_conf.hh b/paludis/environments/paludis/suggestions_conf.hh new file mode 100644 index 000000000..64cc9892c --- /dev/null +++ b/paludis/environments/paludis/suggestions_conf.hh @@ -0,0 +1,67 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 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 + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_ENVIRONMENTS_PALUDIS_SUGGESTIONS_CONF_HH +#define PALUDIS_GUARD_PALUDIS_ENVIRONMENTS_PALUDIS_SUGGESTIONS_CONF_HH 1 + +#include <paludis/util/pimp.hh> +#include <paludis/util/fs_path-fwd.hh> +#include <paludis/util/tribool.hh> +#include <paludis/output_manager-fwd.hh> +#include <paludis/create_output_manager_info-fwd.hh> +#include <paludis/package_id-fwd.hh> +#include <paludis/dep_spec-fwd.hh> +#include <memory> + +namespace paludis +{ + class PaludisEnvironment; + + namespace paludis_environment + { + class SuggestionsConf : + private Pimp<SuggestionsConf> + { + public: + ///\name Basic operations + ///\{ + + SuggestionsConf(const PaludisEnvironment * const); + ~SuggestionsConf(); + + SuggestionsConf(const SuggestionsConf &) = delete; + SuggestionsConf & operator= (const SuggestionsConf &) = delete; + + ///\} + + /** + * Add another file. + */ + void add(const FSPath &); + + Tribool interest_in_suggestion( + const std::shared_ptr<const PackageID> & from_id, + const PackageDepSpec & spec) const; + }; + } + + extern template class Pimp<paludis_environment::SuggestionsConf>; +} + +#endif |