suggestions.conf

This commit is contained in:
Ciaran McCreesh 2010-12-17 02:48:11 +00:00
parent 0c0ff58119
commit 305b1695e0
10 changed files with 378 additions and 20 deletions

@ -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

@ -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

@ -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 \

@ -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")
));
}

@ -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;
};

@ -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
{

@ -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;
///\}

@ -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>

@ -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>;

@ -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