aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-12-17 02:48:11 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-12-17 02:48:11 +0000
commit305b1695e05b9f013d4a09e47054d546afbc2207 (patch)
tree52bf8829ff3e72708ab8ea87a9e77d44ae4f1129
parent0c0ff58119066f55febdc6b2936e75d74fb9587a (diff)
downloadpaludis-305b1695e05b9f013d4a09e47054d546afbc2207.tar.gz
paludis-305b1695e05b9f013d4a09e47054d546afbc2207.tar.xz
suggestions.conf
-rw-r--r--paludis/distributions/exherbo/paludis.conf1
-rw-r--r--paludis/distributions/gentoo/paludis.conf1
-rw-r--r--paludis/environments/paludis/Makefile.am36
-rw-r--r--paludis/environments/paludis/extra_distribution_data.cc1
-rw-r--r--paludis/environments/paludis/extra_distribution_data.hh2
-rw-r--r--paludis/environments/paludis/paludis_config.cc35
-rw-r--r--paludis/environments/paludis/paludis_config.hh2
-rw-r--r--paludis/environments/paludis/paludis_environment.cc7
-rw-r--r--paludis/environments/paludis/suggestions_conf.cc246
-rw-r--r--paludis/environments/paludis/suggestions_conf.hh67
10 files changed, 378 insertions, 20 deletions
diff --git a/paludis/distributions/exherbo/paludis.conf b/paludis/distributions/exherbo/paludis.conf
index 4506ae8..0b0c21a 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 db707ed..2899ea6 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 0c5106e..0703e19 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 4170948..af09445 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 aa49b8d..09b05ab 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 3d98e7b..ac8619f 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 210be8c..843f6f3 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 2e76cc8..ea98e6d 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 0000000..e277dce
--- /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 0000000..64cc989
--- /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