diff options
Diffstat (limited to '0.8.0/paludis/environment')
16 files changed, 2354 insertions, 0 deletions
diff --git a/0.8.0/paludis/environment/Makefile.am b/0.8.0/paludis/environment/Makefile.am new file mode 100644 index 000000000..66c2ccb6d --- /dev/null +++ b/0.8.0/paludis/environment/Makefile.am @@ -0,0 +1,6 @@ +SUBDIRS = default no_config test + +CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda +MAINTAINERCLEANFILES = Makefile.in + + diff --git a/0.8.0/paludis/environment/default/Makefile.am b/0.8.0/paludis/environment/default/Makefile.am new file mode 100644 index 000000000..9ca00d067 --- /dev/null +++ b/0.8.0/paludis/environment/default/Makefile.am @@ -0,0 +1,47 @@ +CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda +MAINTAINERCLEANFILES = Makefile.in +AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@ +DEFS= \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DDATADIR=\"$(datadir)\" \ + -DLIBDIR=\"$(libdir)\" + +libpaludisdefaultenvironment_la_SOURCES = \ + default_config.cc default_config.hh \ + default_environment.cc default_environment.hh + +libpaludisdefaultenvironment_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0 +libpaludisdefaultenvironment_la_LIBADD = \ + $(top_builddir)/paludis/util/libpaludisutil.la \ + $(top_builddir)/paludis/libpaludis.la + +lib_LTLIBRARIES = libpaludisdefaultenvironment.la +paludis_environment_default_includedir = $(includedir)/paludis/environment/test +paludis_environment_default_include_HEADERS = default_config.hh default_environment.hh + +EXTRA_DIST = \ + default_environment_TEST_setup.sh \ + default_environment_TEST.cc \ + default_environment_TEST_cleanup.sh + +TESTS = default_environment_TEST + +TESTS_ENVIRONMENT = env \ + PALUDIS_EBUILD_DIR="$(top_srcdir)/ebuild/" \ + PALUDIS_SKIP_CONFIG="yes" \ + PALUDIS_REPOSITORY_SO_DIR="$(top_builddir)/paludis/repositories" \ + TEST_SCRIPT_DIR="$(srcdir)/" \ + bash $(top_srcdir)/test/run_test.sh + +check_PROGRAMS = $(TESTS) +check_SCRIPTS = default_environment_TEST_setup.sh default_environment_TEST_cleanup.sh + +default_environment_TEST_SOURCES = default_environment_TEST.cc +default_environment_TEST_LDADD = \ + $(top_builddir)/paludis/util/test_extras.o \ + $(top_builddir)/test/libtest.a \ + $(top_builddir)/paludis/libpaludis.la \ + $(top_builddir)/paludis/util/libpaludisutil.la \ + libpaludisdefaultenvironment.la + diff --git a/0.8.0/paludis/environment/default/default_config.cc b/0.8.0/paludis/environment/default/default_config.cc new file mode 100644 index 000000000..a6052806b --- /dev/null +++ b/0.8.0/paludis/environment/default/default_config.cc @@ -0,0 +1,740 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * 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/environment/default/default_config.hh> +#include <paludis/config_file.hh> +#include <paludis/util/collection_concrete.hh> +#include <paludis/util/compare.hh> +#include <paludis/util/destringify.hh> +#include <paludis/util/dir_iterator.hh> +#include <paludis/util/iterator.hh> +#include <paludis/util/fs_entry.hh> +#include <paludis/util/is_file_with_extension.hh> +#include <paludis/util/log.hh> +#include <paludis/util/stringify.hh> +#include <paludis/util/sr.hh> +#include <paludis/util/system.hh> +#include <paludis/util/tokeniser.hh> + +#include <fstream> +#include <algorithm> +#include <sstream> +#include <list> +#include <map> + +#include <ctype.h> + +/** \file + * Implementation of default_config.hh classes. + * + * \ingroup grpdefaultconfig + */ + +using namespace paludis; + +#include <paludis/repository_config_entry-sr.cc> +#include <paludis/use_config_entry-sr.cc> + +namespace paludis +{ + /** + * Implementation data for DefaultConfig. + * + * \ingroup grpdefaultconfig + */ + template<> + struct Implementation<DefaultConfig> : + InternalCounted<DefaultConfig>, + InstantiationPolicy<DefaultConfig, instantiation_method::NonCopyableTag> + { + static std::string config_suffix; + static bool config_suffix_can_be_set; + std::string paludis_command; + std::string root; + std::string config_dir; + std::string bashrc_files; + + std::list<RepositoryConfigEntry> repos; + + std::map<QualifiedPackageName, std::vector< + std::pair<PackageDepAtom::ConstPointer, KeywordName> > > keywords; + + const std::vector<std::pair<PackageDepAtom::ConstPointer, KeywordName> > empty_keywords; + + std::vector<KeywordName> default_keywords; + + std::map<QualifiedPackageName, std::vector< + std::pair<PackageDepAtom::ConstPointer, std::string> > > licenses; + + const std::vector<std::pair<PackageDepAtom::ConstPointer, std::string> > empty_licenses; + + std::vector<std::string> default_licenses; + + std::map<QualifiedPackageName, std::vector<PackageDepAtom::ConstPointer> > user_masks; + + std::map<QualifiedPackageName, std::vector<PackageDepAtom::ConstPointer> > user_unmasks; + + std::vector<PackageDepAtom::ConstPointer> empty_masks; + + std::map<QualifiedPackageName, std::vector<UseConfigEntry> > use; + + std::vector<std::pair<PackageDepAtom::ConstPointer, std::string> > empty_use_prefixes; + + std::map<QualifiedPackageName, std::vector<std::pair<PackageDepAtom::ConstPointer, std::string> > > + use_prefixes_that_have_minus_star; + + std::vector<UseConfigEntry> empty_use; + + std::vector<std::pair<UseFlagName, UseFlagState> > default_use; + + std::vector<std::string> default_use_prefixes_that_have_minus_star; + + std::multimap<std::string, std::string> mirrors; + + Implementation(); + }; + + Implementation<DefaultConfig>::Implementation() : + paludis_command("paludis"), + config_dir("(unset)") + { + } + + std::string Implementation<DefaultConfig>::config_suffix; + bool Implementation<DefaultConfig>::config_suffix_can_be_set(true); +} + +DefaultConfigError::DefaultConfigError(const std::string & msg) throw () : + ConfigurationError("Default configuration error: " + msg) +{ +} + +DefaultConfig::DefaultConfig() : + PrivateImplementationPattern<DefaultConfig>(new Implementation<DefaultConfig>) +{ + Context context("When loading default configuration:"); + + if (! getenv_with_default("PALUDIS_SKIP_CONFIG", "").empty()) + { + _imp->config_suffix_can_be_set = false; + return; + } + + /* indirection */ + std::string root_prefix; + std::string local_config_suffix; + if (! _imp->config_suffix.empty()) + local_config_suffix = "-" + _imp->config_suffix; + + FSEntry local_config_dir(FSEntry(getenv_with_default("PALUDIS_HOME", getenv_or_error("HOME"))) / + (".paludis" + local_config_suffix)), old_config_dir(local_config_dir); + if (! local_config_dir.exists()) + local_config_dir = (FSEntry(SYSCONFDIR) / ("paludis" + local_config_suffix)); + if (! local_config_dir.exists()) + throw DefaultConfigError("Can't find configuration directory (tried '" + + stringify(old_config_dir) + "', '" + stringify(local_config_dir) + "')"); + + Log::get_instance()->message(ll_debug, lc_no_context, "DefaultConfig initial directory is '" + + stringify(local_config_dir) + "'"); + + if ((local_config_dir / "specpath").exists()) + { + KeyValueConfigFile specpath(local_config_dir / "specpath"); + root_prefix = specpath.get("root"); + local_config_suffix = specpath.get("config-suffix"); + + if (! root_prefix.empty() && stringify(FSEntry(root_prefix).realpath()) != "/") + { + local_config_dir = FSEntry(root_prefix) / SYSCONFDIR / ("paludis" + local_config_suffix); + if (! local_config_dir.exists()) + throw DefaultConfigError("Can't find configuration directory under root (" + "tried '" + stringify(local_config_dir) + "'"); + } + } + + _imp->root = root_prefix; + _imp->config_dir = stringify(local_config_dir); + + AssociativeCollection<std::string, std::string>::Pointer conf_vars( + new AssociativeCollection<std::string, std::string>::Concrete); + conf_vars->insert("ROOT", root_prefix); + + Log::get_instance()->message(ll_debug, lc_no_context, "DefaultConfig real directory is '" + + stringify(local_config_dir) + "', root prefix is '" + root_prefix + + "', config suffix is '" + local_config_suffix + "'"); + + /* repositories */ + { + std::list<FSEntry> dirs; + dirs.push_back(local_config_dir / "repositories"); + + std::list<FSEntry> repo_files; + for (std::list<FSEntry>::const_iterator dir(dirs.begin()), dir_end(dirs.end()) ; + dir != dir_end ; ++dir) + { + if (! dir->exists()) + continue; + + std::copy(DirIterator(*dir), DirIterator(), + filter_inserter(std::back_inserter(repo_files), IsFileWithExtension(".conf"))); + } + + for (std::list<FSEntry>::const_iterator repo_file(repo_files.begin()), repo_file_end(repo_files.end()) ; + repo_file != repo_file_end ; ++repo_file) + { + Context local_context("When reading repository file '" + stringify(*repo_file) + "':"); + + KeyValueConfigFile k(*repo_file, conf_vars); + + std::string format(k.get("format")); + if (format.empty()) + throw DefaultConfigError("Key 'format' not specified or empty"); + + int importance(0); + if (! k.get("importance").empty()) + importance = destringify<int>(k.get("importance")); + + AssociativeCollection<std::string, std::string>::Pointer keys( + new AssociativeCollection<std::string, std::string>::Concrete(k.begin(), k.end())); + + keys->erase("repo_file"); + keys->insert("repo_file", stringify(*repo_file)); + + keys->erase("root"); + keys->insert("root", root_prefix); + + _imp->repos.push_back(RepositoryConfigEntry(format, importance, keys)); + } + + if (_imp->repos.empty()) + throw DefaultConfigError("No repositories specified"); + + /* add virtuals repositories */ + _imp->repos.push_back(RepositoryConfigEntry("installed_virtuals", -1, + AssociativeCollection<std::string, std::string>::Pointer(0))); + _imp->repos.push_back(RepositoryConfigEntry("virtuals", -2, + AssociativeCollection<std::string, std::string>::Pointer(0))); + + _imp->repos.sort(); + } + + /* keywords */ + { + std::list<FSEntry> files; + files.push_back(local_config_dir / "keywords.conf"); + + for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ; + file != file_end ; ++file) + { + Context local_context("When reading keywords file '" + stringify(*file) + "':"); + + if (! file->is_regular_file()) + continue; + + LineConfigFile f(*file); + for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ; + line != line_end ; ++line) + { + std::vector<std::string> tokens; + WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens)); + if (tokens.empty()) + continue; + if ("*" == tokens.at(0)) + std::copy(next(tokens.begin()), tokens.end(), + create_inserter<KeywordName>(std::back_inserter(_imp->default_keywords))); + else + { + PackageDepAtom::ConstPointer a(new PackageDepAtom(tokens.at(0))); + for (std::vector<std::string>::const_iterator t(next(tokens.begin())), t_end(tokens.end()) ; + t != t_end ; ++t) + _imp->keywords[a->package()].push_back(std::make_pair(a, *t)); + } + } + } + + if (_imp->default_keywords.empty()) + throw DefaultConfigError("No default keywords specified (a keywords.conf file should " + "contain an entry in the form '* keyword')"); + } + + /* licenses */ + { + std::list<FSEntry> files; + files.push_back(local_config_dir / "licenses.conf"); + + for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ; + file != file_end ; ++file) + { + Context local_context("When reading licenses file '" + stringify(*file) + "':"); + + if (! file->is_regular_file()) + continue; + + LineConfigFile f(*file); + for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ; + line != line_end ; ++line) + { + std::vector<std::string> tokens; + WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens)); + if (tokens.empty()) + continue; + if ("*" == tokens.at(0)) + std::copy(next(tokens.begin()), tokens.end(), std::back_inserter(_imp->default_licenses)); + else + { + PackageDepAtom::ConstPointer a(new PackageDepAtom(tokens.at(0))); + for (std::vector<std::string>::const_iterator t(next(tokens.begin())), t_end(tokens.end()) ; + t != t_end ; ++t) + _imp->licenses[a->package()].push_back(std::make_pair(a, *t)); + } + } + } + + if (_imp->default_licenses.empty()) + throw DefaultConfigError("No default licenses specified (a licenses.conf file should " + "contain an entry in the form '* license license', or '* *' if you don't want any " + "license filtering)"); + } + + /* user mask */ + { + std::list<FSEntry> files; + files.push_back(local_config_dir / "package_mask.conf"); + + for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ; + file != file_end ; ++file) + { + Context local_context("When reading package_mask file '" + stringify(*file) + "':"); + + if (! file->is_regular_file()) + continue; + + LineConfigFile f(*file); + for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ; + line != line_end ; ++line) + { + PackageDepAtom::ConstPointer a(new PackageDepAtom(*line)); + _imp->user_masks[a->package()].push_back(a); + } + } + } + + /* user unmask */ + { + std::list<FSEntry> files; + files.push_back(local_config_dir / "package_unmask.conf"); + + for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ; + file != file_end ; ++file) + { + Context local_context("When reading package_unmask file '" + stringify(*file) + "':"); + + if (! file->is_regular_file()) + continue; + + LineConfigFile f(*file); + for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ; + line != line_end ; ++line) + { + PackageDepAtom::ConstPointer a(new PackageDepAtom(*line)); + _imp->user_unmasks[a->package()].push_back(a); + } + } + } + + /* use */ + { + std::list<FSEntry> files; + files.push_back(local_config_dir / "use.conf"); + + for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ; + file != file_end ; ++file) + { + Context local_context("When reading use file '" + stringify(*file) + "':"); + + if (! file->is_regular_file()) + continue; + + LineConfigFile f(*file); + for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ; + line != line_end ; ++line) + { + std::vector<std::string> tokens; + WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens)); + if (tokens.empty()) + continue; + + std::string prefix; + if ("*" == tokens.at(0)) + { + for (std::vector<std::string>::const_iterator t(next(tokens.begin())), t_end(tokens.end()) ; + t != t_end ; ++t) + { + if ('-' == t->at(0)) + { + if (*t == "-*") + { + _imp->default_use_prefixes_that_have_minus_star.push_back(prefix); + if (prefix.empty()) + Log::get_instance()->message(ll_warning, lc_no_context, + "Using '* -*' in use.conf is dangerous. You have been warned."); + } + else + _imp->default_use.push_back(std::make_pair(UseFlagName( + prefix + t->substr(1)), use_disabled)); + } + else if (':' == t->at(t->length() - 1)) + { + prefix.clear(); + std::transform(t->begin(), previous(t->end()), std::back_inserter(prefix), + &::tolower); + prefix.append("_"); + } + else + _imp->default_use.push_back(std::make_pair(UseFlagName( + prefix + *t), use_enabled)); + } + } + else + { + PackageDepAtom::ConstPointer a(new PackageDepAtom(tokens.at(0))); + for (std::vector<std::string>::const_iterator t(next(tokens.begin())), t_end(tokens.end()) ; + t != t_end ; ++t) + { + if ('-' == t->at(0)) + { + if ("-*" == *t) + _imp->use_prefixes_that_have_minus_star[a->package()].push_back( + std::make_pair(a, prefix)); + else + _imp->use[a->package()].push_back(UseConfigEntry( + a, UseFlagName(prefix + t->substr(1)), use_disabled)); + } + else if (':' == t->at(t->length() - 1)) + { + prefix.clear(); + std::transform(t->begin(), previous(t->end()), std::back_inserter(prefix), + &::tolower); + prefix.append("_"); + } + else + _imp->use[a->package()].push_back(UseConfigEntry( + a, UseFlagName(prefix + *t), use_enabled)); + } + } + } + } + + if (_imp->default_keywords.empty()) + throw DefaultConfigError("No default keywords specified (a keywords.conf file should " + "contain an entry in the form '* keyword')"); + } + + /* mirrors */ + { + std::list<FSEntry> files; + files.push_back(local_config_dir / "mirrors.conf"); + + for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ; + file != file_end ; ++file) + { + Context local_context("When reading mirrors file '" + stringify(*file) + "':"); + + if (! file->is_regular_file()) + continue; + + LineConfigFile f(*file); + for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ; + line != line_end ; ++line) + { + std::vector<std::string> m; + WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(m)); + if (m.size() < 2) + continue; + for (std::vector<std::string>::const_iterator mm(next(m.begin())), + mm_end(m.end()) ; mm != mm_end ; ++mm) + _imp->mirrors.insert(std::make_pair(m.at(0), *mm)); + } + } + } + + _imp->bashrc_files = stringify(local_config_dir / "bashrc"); + + _imp->config_suffix_can_be_set = false; +} + +DefaultConfig::~DefaultConfig() +{ +} + +void +DefaultConfig::set_config_suffix(const std::string & s) +{ + if (! Implementation<DefaultConfig>::config_suffix_can_be_set) + throw InternalError(PALUDIS_HERE, "DefaultConfig::set_config_suffix called after " + "DefaultConfig has been instantiated."); + + static const std::string allowed_chars( + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789-_+:"); + + if (std::string::npos != s.find_first_not_of(allowed_chars)) + throw DefaultConfigError("Invalid config suffix '" + s + "'"); + + if (! s.empty()) + if ('-' == s.at(0) || '-' == s.at(s.length() - 1)) + throw DefaultConfigError("Invalid config suffix '" + s + "'"); + + Implementation<DefaultConfig>::config_suffix = s; +} + +std::string +DefaultConfig::bashrc_files() const +{ + return _imp->bashrc_files; +} + +std::string +DefaultConfig::config_suffix() +{ + return Implementation<DefaultConfig>::config_suffix; +} + +DefaultConfig::RepositoryIterator +DefaultConfig::begin_repositories() const +{ + return RepositoryIterator(_imp->repos.begin()); +} + +DefaultConfig::RepositoryIterator +DefaultConfig::end_repositories() const +{ + return RepositoryIterator(_imp->repos.end()); +} + +DefaultConfig::PackageKeywordsIterator +DefaultConfig::begin_package_keywords(const QualifiedPackageName & d) const +{ + std::map<QualifiedPackageName, std::vector< + std::pair<PackageDepAtom::ConstPointer, KeywordName> > >::const_iterator r; + if (_imp->keywords.end() != ((r = _imp->keywords.find(d)))) + return PackageKeywordsIterator(r->second.begin()); + else + return PackageKeywordsIterator(_imp->empty_keywords.begin()); +} + +DefaultConfig::PackageKeywordsIterator +DefaultConfig::end_package_keywords(const QualifiedPackageName & d) const +{ + std::map<QualifiedPackageName, std::vector< + std::pair<PackageDepAtom::ConstPointer, KeywordName> > >::const_iterator r; + if (_imp->keywords.end() != ((r = _imp->keywords.find(d)))) + return PackageKeywordsIterator(r->second.end()); + else + return PackageKeywordsIterator(_imp->empty_keywords.end()); +} + +DefaultConfig::DefaultKeywordsIterator +DefaultConfig::begin_default_keywords() const +{ + return DefaultKeywordsIterator(_imp->default_keywords.begin()); +} + +DefaultConfig::DefaultKeywordsIterator +DefaultConfig::end_default_keywords() const +{ + return DefaultKeywordsIterator(_imp->default_keywords.end()); +} + +DefaultConfig::PackageLicensesIterator +DefaultConfig::begin_package_licenses(const QualifiedPackageName & d) const +{ + std::map<QualifiedPackageName, std::vector< + std::pair<PackageDepAtom::ConstPointer, std::string> > >::const_iterator r; + if (_imp->licenses.end() != ((r = _imp->licenses.find(d)))) + return PackageLicensesIterator(r->second.begin()); + else + return PackageLicensesIterator(_imp->empty_licenses.begin()); +} + +DefaultConfig::PackageLicensesIterator +DefaultConfig::end_package_licenses(const QualifiedPackageName & d) const +{ + std::map<QualifiedPackageName, std::vector< + std::pair<PackageDepAtom::ConstPointer, std::string> > >::const_iterator r; + if (_imp->licenses.end() != ((r = _imp->licenses.find(d)))) + return PackageLicensesIterator(r->second.end()); + else + return PackageLicensesIterator(_imp->empty_licenses.end()); +} + +DefaultConfig::DefaultLicensesIterator +DefaultConfig::begin_default_licenses() const +{ + return DefaultLicensesIterator(_imp->default_licenses.begin()); +} + +DefaultConfig::DefaultLicensesIterator +DefaultConfig::end_default_licenses() const +{ + return DefaultLicensesIterator(_imp->default_licenses.end()); +} + +DefaultConfig::UserMasksIterator +DefaultConfig::begin_user_masks(const QualifiedPackageName & d) const +{ + std::map<QualifiedPackageName, std::vector<PackageDepAtom::ConstPointer> >::const_iterator r; + if (_imp->user_masks.end() != ((r = _imp->user_masks.find(d)))) + return UserMasksIterator(indirect_iterator<const PackageDepAtom>(r->second.begin())); + else + return UserMasksIterator(indirect_iterator<const PackageDepAtom>(_imp->empty_masks.begin())); +} + +DefaultConfig::UserMasksIterator +DefaultConfig::end_user_masks(const QualifiedPackageName & d) const +{ + std::map<QualifiedPackageName, std::vector<PackageDepAtom::ConstPointer> >::const_iterator r; + if (_imp->user_masks.end() != ((r = _imp->user_masks.find(d)))) + return UserMasksIterator(indirect_iterator<const PackageDepAtom>(r->second.end())); + else + return UserMasksIterator(indirect_iterator<const PackageDepAtom>(_imp->empty_masks.end())); +} + +DefaultConfig::UserUnmasksIterator +DefaultConfig::begin_user_unmasks(const QualifiedPackageName & d) const +{ + std::map<QualifiedPackageName, std::vector<PackageDepAtom::ConstPointer> >::const_iterator r; + if (_imp->user_unmasks.end() != ((r = _imp->user_unmasks.find(d)))) + return UserUnmasksIterator(indirect_iterator<const PackageDepAtom>(r->second.begin())); + else + return UserUnmasksIterator(indirect_iterator<const PackageDepAtom>(_imp->empty_masks.begin())); +} + +DefaultConfig::UserUnmasksIterator +DefaultConfig::end_user_unmasks(const QualifiedPackageName & d) const +{ + std::map<QualifiedPackageName, std::vector<PackageDepAtom::ConstPointer> >::const_iterator r; + if (_imp->user_unmasks.end() != ((r = _imp->user_unmasks.find(d)))) + return UserUnmasksIterator(indirect_iterator<const PackageDepAtom>(r->second.end())); + else + return UserUnmasksIterator(indirect_iterator<const PackageDepAtom>(_imp->empty_masks.end())); +} + +DefaultConfig::UseConfigIterator +DefaultConfig::begin_use_config(const QualifiedPackageName & q) const +{ + std::map<QualifiedPackageName, std::vector<UseConfigEntry> >::const_iterator r; + if (_imp->use.end() != ((r = _imp->use.find(q)))) + return UseConfigIterator(r->second.begin()); + else + return UseConfigIterator(_imp->empty_use.begin()); +} + +DefaultConfig::UseConfigIterator +DefaultConfig::end_use_config(const QualifiedPackageName & q) const +{ + std::map<QualifiedPackageName, std::vector<UseConfigEntry> >::const_iterator r; + if (_imp->use.end() != ((r = _imp->use.find(q)))) + return UseConfigIterator(r->second.end()); + else + return UseConfigIterator(_imp->empty_use.end()); +} + +DefaultConfig::DefaultUseIterator +DefaultConfig::begin_default_use() const +{ + return DefaultUseIterator(_imp->default_use.begin()); +} + +DefaultConfig::DefaultUseIterator +DefaultConfig::end_default_use() const +{ + return DefaultUseIterator(_imp->default_use.end()); +} + +std::string +DefaultConfig::paludis_command() const +{ + return _imp->paludis_command; +} + +void +DefaultConfig::set_paludis_command(const std::string & s) +{ + _imp->paludis_command = s; +} + +std::string +DefaultConfig::root() const +{ + return _imp->root; +} + +std::string +DefaultConfig::config_dir() const +{ + return _imp->config_dir; +} + +DefaultConfig::MirrorIterator +DefaultConfig::begin_mirrors(const std::string & m) const +{ + return MirrorIterator(_imp->mirrors.lower_bound(m)); +} + +DefaultConfig::MirrorIterator +DefaultConfig::end_mirrors(const std::string & m) const +{ + return MirrorIterator(_imp->mirrors.upper_bound(m)); +} + +DefaultConfig::UseMinusStarIterator +DefaultConfig::begin_use_prefixes_with_minus_star() const +{ + return UseMinusStarIterator(_imp->default_use_prefixes_that_have_minus_star.begin()); +} + +DefaultConfig::UseMinusStarIterator +DefaultConfig::end_use_prefixes_with_minus_star() const +{ + return UseMinusStarIterator(_imp->default_use_prefixes_that_have_minus_star.end()); +} + +DefaultConfig::PackageUseMinusStarIterator +DefaultConfig::begin_package_use_prefixes_with_minus_star(const QualifiedPackageName & d) const +{ + std::map<QualifiedPackageName, std::vector<std::pair<PackageDepAtom::ConstPointer, std::string> > >::const_iterator r; + if (_imp->use_prefixes_that_have_minus_star.end() != ((r = _imp->use_prefixes_that_have_minus_star.find(d)))) + return PackageUseMinusStarIterator(r->second.begin()); + else + return PackageUseMinusStarIterator(_imp->empty_use_prefixes.begin()); +} + +DefaultConfig::PackageUseMinusStarIterator +DefaultConfig::end_package_use_prefixes_with_minus_star(const QualifiedPackageName & d) const +{ + std::map<QualifiedPackageName, std::vector<std::pair<PackageDepAtom::ConstPointer, std::string> > >::const_iterator r; + if (_imp->use_prefixes_that_have_minus_star.end() != ((r = _imp->use_prefixes_that_have_minus_star.find(d)))) + return PackageUseMinusStarIterator(r->second.end()); + else + return PackageUseMinusStarIterator(_imp->empty_use_prefixes.end()); +} + + diff --git a/0.8.0/paludis/environment/default/default_config.hh b/0.8.0/paludis/environment/default/default_config.hh new file mode 100644 index 000000000..03a09f5c0 --- /dev/null +++ b/0.8.0/paludis/environment/default/default_config.hh @@ -0,0 +1,224 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * 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_DEFAULT_CONFIG_HH +#define PALUDIS_GUARD_PALUDIS_DEFAULT_CONFIG_HH 1 + +#include <paludis/dep_atom.hh> +#include <paludis/name.hh> +#include <paludis/util/collection.hh> +#include <paludis/util/exception.hh> +#include <paludis/util/instantiation_policy.hh> +#include <paludis/util/sr.hh> + +#include <string> + +/** \file + * Declarations for the DefaultConfig class and related utilities. + * + * \ingroup grpdefaultconfig + */ + +namespace paludis +{ + struct EnvironmentMirrorIteratorTag; + + typedef libwrapiter::ForwardIterator<EnvironmentMirrorIteratorTag, + const std::pair<const std::string, std::string> > EnvironmentMirrorIterator; + + /** + * A DefaultConfigError is thrown if a configuration error is encountered + * by DefaultConfig. + * + * \ingroup grpexceptions + * \ingroup grpdefaultconfig + */ + class PALUDIS_VISIBLE DefaultConfigError : public ConfigurationError + { + public: + /** + * Constructor. + */ + DefaultConfigError(const std::string & msg) throw (); + }; + +#include <paludis/repository_config_entry-sr.hh> +#include <paludis/use_config_entry-sr.hh> + + /** + * DefaultConfig is used by DefaultEnvironment to access the user's + * configuration settings from on-disk configuration files. + * + * \ingroup grpdefaultconfig + */ + class PALUDIS_VISIBLE DefaultConfig : + public InstantiationPolicy<DefaultConfig, instantiation_method::SingletonAsNeededTag>, + private PrivateImplementationPattern<DefaultConfig> + { + friend class InstantiationPolicy<DefaultConfig, instantiation_method::SingletonAsNeededTag>; + + private: + DefaultConfig(); + + ~DefaultConfig(); + + public: + /** + * Set config suffix. Must be called before we do anything, or not + * at all. + */ + static void set_config_suffix(const std::string &); + + /** + * Get config suffix. + */ + static std::string config_suffix(); + + ///\name Iterate over our repositories + ///{ + + typedef libwrapiter::ForwardIterator<DefaultConfig, const RepositoryConfigEntry> RepositoryIterator; + + RepositoryIterator begin_repositories() const; + + RepositoryIterator end_repositories() const; + + ///} + + ///\name Iterate over our default and per-package keywords + ///{ + + typedef libwrapiter::ForwardIterator<DefaultConfig, + const std::pair<PackageDepAtom::ConstPointer, KeywordName> > PackageKeywordsIterator; + + PackageKeywordsIterator begin_package_keywords(const QualifiedPackageName & d) const; + + PackageKeywordsIterator end_package_keywords(const QualifiedPackageName & d) const; + + typedef libwrapiter::ForwardIterator<DefaultConfig, const KeywordName> DefaultKeywordsIterator; + + DefaultKeywordsIterator begin_default_keywords() const; + + DefaultKeywordsIterator end_default_keywords() const; + + ///} + + ///\name Iterate over our default and per-package licenses + ///{ + + typedef libwrapiter::ForwardIterator<DefaultConfig, + const std::pair<PackageDepAtom::ConstPointer, std::string> > PackageLicensesIterator; + + PackageLicensesIterator begin_package_licenses(const QualifiedPackageName & d) const; + + PackageLicensesIterator end_package_licenses(const QualifiedPackageName & d) const; + + typedef libwrapiter::ForwardIterator<DefaultConfig, const std::string> DefaultLicensesIterator; + + DefaultLicensesIterator begin_default_licenses() const; + + DefaultLicensesIterator end_default_licenses() const; + + ///} + + ///\name Iterate over our masks and unmasks + ///{ + + typedef libwrapiter::ForwardIterator<DefaultConfig, const PackageDepAtom> UserMasksIterator; + + UserMasksIterator begin_user_masks(const QualifiedPackageName & d) const; + + UserMasksIterator end_user_masks(const QualifiedPackageName & d) const; + + typedef libwrapiter::ForwardIterator<DefaultConfig, const PackageDepAtom> UserUnmasksIterator; + + UserUnmasksIterator begin_user_unmasks(const QualifiedPackageName & d) const; + + UserUnmasksIterator end_user_unmasks(const QualifiedPackageName & d) const; + + ///} + + ///\name Iterate over our default and per-package use flags + ///{ + + typedef libwrapiter::ForwardIterator<DefaultConfig, const UseConfigEntry> UseConfigIterator; + + UseConfigIterator begin_use_config(const QualifiedPackageName & q) const; + + UseConfigIterator end_use_config(const QualifiedPackageName & q) const; + + typedef libwrapiter::ForwardIterator<DefaultConfig, + const std::pair<UseFlagName, UseFlagState> > DefaultUseIterator; + + DefaultUseIterator begin_default_use() const; + + DefaultUseIterator end_default_use() const; + + typedef libwrapiter::ForwardIterator<DefaultConfig, const std::string> UseMinusStarIterator; + + UseMinusStarIterator begin_use_prefixes_with_minus_star() const; + UseMinusStarIterator end_use_prefixes_with_minus_star() const; + + typedef libwrapiter::ForwardIterator<DefaultConfig, + const std::pair<PackageDepAtom::ConstPointer, std::string> > PackageUseMinusStarIterator; + + PackageUseMinusStarIterator begin_package_use_prefixes_with_minus_star(const QualifiedPackageName &) const; + PackageUseMinusStarIterator end_package_use_prefixes_with_minus_star(const QualifiedPackageName &) const; + + ///} + + /** + * Our bashrc files. + */ + std::string bashrc_files() const; + + /** + * The paludis command. + */ + std::string paludis_command() const; + + /** + * Set the paludis command. + */ + void set_paludis_command(const std::string & s); + + /** + * The ROOT. + */ + std::string root() const; + + /** + * The config directory. + */ + std::string config_dir() const; + + ///\name Iterate over our mirrors + ///\{ + + typedef EnvironmentMirrorIterator MirrorIterator; + + MirrorIterator begin_mirrors(const std::string & m) const; + + MirrorIterator end_mirrors(const std::string & m) const; + + ///\} + }; +} + +#endif diff --git a/0.8.0/paludis/environment/default/default_environment.cc b/0.8.0/paludis/environment/default/default_environment.cc new file mode 100644 index 000000000..a0a1f0176 --- /dev/null +++ b/0.8.0/paludis/environment/default/default_environment.cc @@ -0,0 +1,530 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * 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 <list> +#include <paludis/config_file.hh> +#include <paludis/environment/default/default_config.hh> +#include <paludis/environment/default/default_environment.hh> +#include <paludis/match_package.hh> +#include <paludis/package_database.hh> +#include <paludis/repository.hh> +#include <paludis/util/collection_concrete.hh> +#include <paludis/util/is_file_with_extension.hh> +#include <paludis/util/log.hh> +#include <paludis/util/stringify.hh> +#include <paludis/util/system.hh> +#include <paludis/util/tokeniser.hh> +#include <paludis/util/dir_iterator.hh> +#include <vector> + +using namespace paludis; + +DefaultEnvironment::DefaultEnvironment() : + Environment(PackageDatabase::Pointer(new PackageDatabase(this))) +{ + Context context("When loading default environment:"); + + for (DefaultConfig::RepositoryIterator r(DefaultConfig::get_instance()->begin_repositories()), + r_end(DefaultConfig::get_instance()->end_repositories()) ; r != r_end ; ++r) + package_database()->add_repository( + RepositoryMaker::get_instance()->find_maker(r->format)( + this, package_database().raw_pointer(), r->keys)); +} + +DefaultEnvironment::~DefaultEnvironment() +{ +} + +bool +DefaultEnvironment::query_use(const UseFlagName & f, const PackageDatabaseEntry * e) const +{ + /* first check package database use masks... */ + const Repository * const repo((e ? + package_database()->fetch_repository(e->repository).raw_pointer() : + 0)); + + if (repo && repo->use_interface) + { + if (repo->use_interface->query_use_mask(f, e)) + return false; + if (repo->use_interface->query_use_force(f, e)) + return true; + } + + /* check use: per package user config */ + if (e) + { + UseFlagState s(use_unspecified); + + for (DefaultConfig::UseConfigIterator + u(DefaultConfig::get_instance()->begin_use_config(e->name)), + u_end(DefaultConfig::get_instance()->end_use_config(e->name)) ; + u != u_end ; ++u) + { + if (f != u->flag_name) + continue; + + if (! match_package(this, *u->dep_atom, *e)) + continue; + + switch (u->flag_state) + { + case use_enabled: + s = use_enabled; + continue; + + case use_disabled: + s = use_disabled; + continue; + + case use_unspecified: + continue; + } + + throw InternalError(PALUDIS_HERE, "Bad state"); + } + + do + { + switch (s) + { + case use_enabled: + return true; + + case use_disabled: + return false; + + case use_unspecified: + continue; + } + throw InternalError(PALUDIS_HERE, "Bad state"); + } while (false); + + /* and the -* bit */ + for (DefaultConfig::PackageUseMinusStarIterator + i(DefaultConfig::get_instance()->begin_package_use_prefixes_with_minus_star(e->name)), + i_end(DefaultConfig::get_instance()->end_package_use_prefixes_with_minus_star(e->name)) ; + i != i_end ; ++i) + { + if (! match_package(this, *i->first, *e)) + continue; + + if (0 == i->second.compare(0, i->second.length(), stringify(f), 0, i->second.length())) + return false; + } + } + + /* check use: general user config */ + do + { + UseFlagState state(use_unspecified); + + for (DefaultConfig::DefaultUseIterator + u(DefaultConfig::get_instance()->begin_default_use()), + u_end(DefaultConfig::get_instance()->end_default_use()) ; + u != u_end ; ++u) + if (f == u->first) + state = u->second; + + switch (state) + { + case use_enabled: + return true; + + case use_disabled: + return false; + + case use_unspecified: + continue; + } + + throw InternalError(PALUDIS_HERE, "bad state " + stringify(state)); + } while (false); + + /* and -* again. slight gotcha: "* -*" should not override use expand things. if it + * does, USERLAND etc get emptied. */ + bool consider_minus_star(true); + if (e && repo && repo->use_interface) + { + UseFlagNameCollection::ConstPointer prefixes(repo->use_interface->use_expand_prefixes()); + for (UseFlagNameCollection::Iterator i(prefixes->begin()), i_end(prefixes->end()) ; + i != i_end ; ++i) + if (0 == i->data().compare(0, i->data().length(), stringify(f), 0, i->data().length())) + { + consider_minus_star = false; + break; + } + } + + for (DefaultConfig::UseMinusStarIterator + i(DefaultConfig::get_instance()->begin_use_prefixes_with_minus_star()), + i_end(DefaultConfig::get_instance()->end_use_prefixes_with_minus_star()) ; + i != i_end ; ++i) + { + if ((! consider_minus_star) && i->empty()) + continue; + if (0 == i->compare(0, i->length(), stringify(f), 0, i->length())) + return false; + } + + /* check use: package database config */ + if (repo && repo->use_interface) + { + switch (repo->use_interface->query_use(f, e)) + { + case use_disabled: + case use_unspecified: + return false; + + case use_enabled: + return true; + } + + throw InternalError(PALUDIS_HERE, "bad state"); + } + else + { + return false; + } +} + +bool +DefaultEnvironment::accept_keyword(const KeywordName & keyword, const PackageDatabaseEntry * const d) const +{ + if (keyword == KeywordName("*")) + return true; + + Context context("When checking accept_keyword of '" + stringify(keyword) + + (d ? "' for " + stringify(*d) : stringify("'")) + ":"); + + bool result(false); + + if (d) + for (DefaultConfig::PackageKeywordsIterator + k(DefaultConfig::get_instance()->begin_package_keywords(d->name)), + k_end(DefaultConfig::get_instance()->end_package_keywords(d->name)) ; + k != k_end ; ++k) + { + if (! match_package(this, k->first, d)) + continue; + + result |= k->second == keyword; + } + + result |= DefaultConfig::get_instance()->end_default_keywords() != + std::find(DefaultConfig::get_instance()->begin_default_keywords(), + DefaultConfig::get_instance()->end_default_keywords(), + keyword); + + return result; +} + +bool +DefaultEnvironment::accept_license(const std::string & license, const PackageDatabaseEntry * const d) const +{ + if (license == "*") + return true; + + Context context("When checking license of '" + license + + (d ? "' for " + stringify(*d) : stringify("'")) + ":"); + + bool result(false); + + if (d) + for (DefaultConfig::PackageLicensesIterator + k(DefaultConfig::get_instance()->begin_package_licenses(d->name)), + k_end(DefaultConfig::get_instance()->end_package_licenses(d->name)) ; + k != k_end ; ++k) + { + if (! match_package(this, k->first, d)) + continue; + + result |= k->second == license; + result |= k->second == "*"; + } + + result |= DefaultConfig::get_instance()->end_default_licenses() != + std::find(DefaultConfig::get_instance()->begin_default_licenses(), + DefaultConfig::get_instance()->end_default_licenses(), + license); + + result |= DefaultConfig::get_instance()->end_default_licenses() != + std::find(DefaultConfig::get_instance()->begin_default_licenses(), + DefaultConfig::get_instance()->end_default_licenses(), + "*"); + + return result; +} + +bool +DefaultEnvironment::query_user_masks(const PackageDatabaseEntry & d) const +{ + for (DefaultConfig::UserMasksIterator + k(DefaultConfig::get_instance()->begin_user_masks(d.name)), + k_end(DefaultConfig::get_instance()->end_user_masks(d.name)) ; + k != k_end ; ++k) + { + if (! match_package(this, *k, d)) + continue; + + return true; + } + + return false; +} + +bool +DefaultEnvironment::query_user_unmasks(const PackageDatabaseEntry & d) const +{ + for (DefaultConfig::UserMasksIterator + k(DefaultConfig::get_instance()->begin_user_unmasks(d.name)), + k_end(DefaultConfig::get_instance()->end_user_unmasks(d.name)) ; + k != k_end ; ++k) + { + if (! match_package(this, *k, d)) + continue; + + return true; + } + + return false; +} + +std::string +DefaultEnvironment::bashrc_files() const +{ + return DefaultConfig::get_instance()->bashrc_files(); +} + +std::string +DefaultEnvironment::paludis_command() const +{ + return DefaultConfig::get_instance()->paludis_command(); +} + +namespace +{ + void add_one_hook(const std::string & base, std::list<FSEntry> & result) + { + try + { + FSEntry r(base); + if (r.is_directory()) + { + Log::get_instance()->message(ll_debug, lc_no_context, "Adding hook directory '" + + base + "'"); + result.push_back(r); + } + else + Log::get_instance()->message(ll_debug, lc_no_context, "Skipping hook directory candidate '" + + base + "'"); + } + catch (const FSError & e) + { + Log::get_instance()->message(ll_warning, lc_no_context, "Caught exception '" + + e.message() + "' (" + e.what() + ") when checking hook " + "directory '" + base + "'"); + } + } + + const std::list<FSEntry> & get_hook_dirs() + { + static std::list<FSEntry> result; + static bool done_hooks(false); + if (! done_hooks) + { + add_one_hook(DefaultConfig::get_instance()->config_dir() + "/hooks", result); + if (getenv_with_default("PALUDIS_NO_GLOBAL_HOOKS", "").empty()) + { + add_one_hook(LIBEXECDIR "/paludis/hooks", result); + add_one_hook(DATADIR "/paludis/hooks", result); + } + done_hooks = true; + } + return result; + } + + struct Hooker + { + Hook hook; + std::string paludis_command; + + Hooker(const Hook & h, const std::string & p) : + hook(h), + paludis_command(p) + { + } + + void operator() (const FSEntry & f) const; + }; + + void + Hooker::operator() (const FSEntry & f) const + { + Context context("When running hook script '" + stringify(f) + + "' for hook '" + hook.name() + "':"); + Log::get_instance()->message(ll_debug, lc_no_context, "Starting hook script '" + + stringify(f) + "' for '" + hook.name() + "'"); + + MakeEnvCommand cmd(make_env_command("bash '" + stringify(f) + "'") + ("ROOT", DefaultConfig::get_instance()->root()) + ("HOOK", hook.name()) + ("HOOK_LOG_LEVEL", stringify(Log::get_instance()->log_level())) + ("HOOK_CONFIG_SUFFIX", DefaultConfig::config_suffix()) + ("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis")) + ("PALUDIS_COMMAND", paludis_command)); + + for (Hook::Iterator h(hook.begin()), h_end(hook.end()) ; h != h_end ; ++h) + cmd = cmd(h->first, h->second); + + int exit_status(run_command(cmd)); + if (0 == exit_status) + Log::get_instance()->message(ll_debug, lc_no_context, "Hook '" + stringify(f) + + "' returned success '" + stringify(exit_status) + "'"); + else + Log::get_instance()->message(ll_warning, lc_no_context, "Hook '" + stringify(f) + + "' returned failure '" + stringify(exit_status) + "'"); + } +} + +void +DefaultEnvironment::perform_hook(const Hook & hook) const +{ + Context context("When triggering hook '" + hook.name() + "'"); + Log::get_instance()->message(ll_debug, lc_no_context, "Starting hook '" + hook.name() + "'"); + + const std::list<FSEntry> & hook_dirs_ref(get_hook_dirs()); + + for (std::list<FSEntry>::const_iterator h(hook_dirs_ref.begin()), + h_end(hook_dirs_ref.end()) ; h != h_end ; ++h) + { + FSEntry hh(*h / hook.name()); + if (! hh.is_directory()) + continue; + + std::list<FSEntry> hooks; + std::copy(DirIterator(hh), DirIterator(), + filter_inserter(std::back_inserter(hooks), IsFileWithExtension(".bash"))); + std::for_each(hooks.begin(), hooks.end(), Hooker(hook, paludis_command())); + } +} + +std::string +DefaultEnvironment::hook_dirs() const +{ + const std::list<FSEntry> & hook_dirs_ref(get_hook_dirs()); + return join(hook_dirs_ref.begin(), hook_dirs_ref.end(), " "); +} + +CompositeDepAtom::Pointer +DefaultEnvironment::local_package_set(const std::string & s) const +{ + Context context("When looking for package set '" + s + "' in default environment:"); + + FSEntry ff(FSEntry(DefaultConfig::get_instance()->config_dir()) / "sets" / (s + ".conf")); + if (ff.exists()) + { + LineConfigFile f(ff); + AllDepAtom::Pointer result(new AllDepAtom); + GeneralSetDepTag::Pointer tag(new GeneralSetDepTag(s)); + + for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ; + line != line_end ; ++line) + { + std::vector<std::string> tokens; + WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens)); + if (tokens.empty()) + continue; + + if (1 == tokens.size()) + { + Log::get_instance()->message(ll_warning, lc_context, "Line '" + *line + "' in set file '" + + stringify(ff) + "' does not specify '*' or '?', assuming '*'"); + PackageDepAtom::Pointer atom(new PackageDepAtom(tokens.at(0))); + atom->set_tag(tag); + result->add_child(atom); + } + else if ("*" == tokens.at(0)) + { + PackageDepAtom::Pointer atom(new PackageDepAtom(tokens.at(1))); + atom->set_tag(tag); + result->add_child(atom); + } + else if ("?" == tokens.at(0)) + { + PackageDepAtom::Pointer p(new PackageDepAtom(tokens.at(1))); + p->set_tag(tag); + if (! package_database()->query( + PackageDepAtom::Pointer(new PackageDepAtom(p->package())), + is_installed_only)->empty()) + result->add_child(p); + } + else + Log::get_instance()->message(ll_warning, lc_context, "Line '" + *line + "' in set file '" + + stringify(ff) + "' does not start with '*' or '?' token, skipping"); + + if (tokens.size() > 2) + Log::get_instance()->message(ll_warning, lc_context, "Line '" + *line + "' in set file '" + + stringify(ff) + "' has trailing garbage"); + } + + return result; + } + + return DepAtom::Pointer(0); +} + +DefaultEnvironment::MirrorIterator +DefaultEnvironment::begin_mirrors(const std::string & mirror) const +{ + return DefaultConfig::get_instance()->begin_mirrors(mirror); +} + +DefaultEnvironment::MirrorIterator +DefaultEnvironment::end_mirrors(const std::string & mirror) const +{ + return DefaultConfig::get_instance()->end_mirrors(mirror); +} + +UseFlagNameCollection::ConstPointer +DefaultEnvironment::known_use_expand_names(const UseFlagName & prefix, const PackageDatabaseEntry * pde) const +{ + UseFlagNameCollection::Pointer result(new UseFlagNameCollection::Concrete); + + std::string prefix_lower; + std::transform(prefix.data().begin(), prefix.data().end(), std::back_inserter(prefix_lower), &::tolower); + for (DefaultConfig::DefaultUseIterator i(DefaultConfig::get_instance()->begin_default_use()), + i_end(DefaultConfig::get_instance()->end_default_use()) ; i != i_end ; ++i) + if (i->first.data().length() > prefix_lower.length() && + 0 == i->first.data().compare(0, prefix_lower.length(), prefix_lower, 0, prefix_lower.length())) + result->insert(i->first); + + if (pde) + for (DefaultConfig::UseConfigIterator i(DefaultConfig::get_instance()->begin_use_config(pde->name)), + i_end(DefaultConfig::get_instance()->end_use_config(pde->name)) ; i != i_end ; ++i) + if (i->flag_name.data().length() > prefix_lower.length() && + 0 == i->flag_name.data().compare(0, prefix_lower.length(), prefix_lower, 0, prefix_lower.length())) + result->insert(i->flag_name); + + Log::get_instance()->message(ll_debug, lc_no_context, "DefaultEnvironment::known_use_expand_names(" + + stringify(prefix) + ", " + (pde ? stringify(*pde) : stringify("0")) + ") -> (" + + join(result->begin(), result->end(), ", ") + ")"); + return result; +} + diff --git a/0.8.0/paludis/environment/default/default_environment.hh b/0.8.0/paludis/environment/default/default_environment.hh new file mode 100644 index 000000000..058a246ec --- /dev/null +++ b/0.8.0/paludis/environment/default/default_environment.hh @@ -0,0 +1,81 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * 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_DEFAULT_ENVIRONMENT_HH +#define PALUDIS_GUARD_PALUDIS_DEFAULT_ENVIRONMENT_HH 1 + +#include <paludis/package_database.hh> +#include <paludis/environment.hh> + +/** \file + * Declarations for the DefaultEnvironment class. + * + * \ingroup grpdefaultenvironment + */ + +namespace paludis +{ + /** + * The DefaultEnvironment is an Environment that corresponds to the normal + * operating evironment. + * + * \ingroup grpdefaultenvironment + */ + class PALUDIS_VISIBLE DefaultEnvironment : + public Environment, + public InstantiationPolicy<DefaultEnvironment, instantiation_method::SingletonAsNeededTag> + { + friend class InstantiationPolicy<DefaultEnvironment, instantiation_method::SingletonAsNeededTag>; + + private: + DefaultEnvironment(); + + ~DefaultEnvironment(); + + protected: + CompositeDepAtom::Pointer local_package_set(const std::string &) const; + + public: + virtual bool query_use(const UseFlagName &, const PackageDatabaseEntry *) const; + + virtual bool accept_keyword(const KeywordName &, const PackageDatabaseEntry * const) const; + + virtual bool accept_license(const std::string &, const PackageDatabaseEntry * const) const; + + virtual bool query_user_masks(const PackageDatabaseEntry &) const; + + virtual bool query_user_unmasks(const PackageDatabaseEntry &) const; + + virtual std::string bashrc_files() const; + + virtual std::string hook_dirs() const; + + virtual std::string paludis_command() const; + + virtual UseFlagNameCollection::ConstPointer known_use_expand_names(const UseFlagName &, + const PackageDatabaseEntry *) const; + + virtual void perform_hook(const Hook & hook) const; + + virtual MirrorIterator begin_mirrors(const std::string & mirror) const; + + virtual MirrorIterator end_mirrors(const std::string & mirror) const; + }; +} +#endif diff --git a/0.8.0/paludis/environment/default/default_environment_TEST.cc b/0.8.0/paludis/environment/default/default_environment_TEST.cc new file mode 100644 index 000000000..fcad357e7 --- /dev/null +++ b/0.8.0/paludis/environment/default/default_environment_TEST.cc @@ -0,0 +1,131 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * 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 "default_environment.hh" +#include "default_config.hh" +#include <paludis/util/fs_entry.hh> +#include <test/test_runner.hh> +#include <test/test_framework.hh> +#include <cstdlib> + +using namespace paludis; +using namespace test; + +namespace test_cases +{ + struct TestDefaultEnvironmentUse : TestCase + { + TestDefaultEnvironmentUse() : TestCase("use") { } + + void run() + { + setenv("PALUDIS_HOME", stringify(FSEntry::cwd() / "default_environment_TEST_dir" / "home1").c_str(), 1); + unsetenv("PALUDIS_SKIP_CONFIG"); + DefaultConfig::destroy_instance(); + DefaultEnvironment::destroy_instance(); + + Environment * env(DefaultEnvironment::get_instance()); + + TEST_CHECK(env->query_use(UseFlagName("foo"), 0)); + TEST_CHECK(! env->query_use(UseFlagName("foofoo"), 0)); + + PackageDatabaseEntry pde(QualifiedPackageName("cat-one/pkg-one"), VersionSpec("1"), RepositoryName("foo")); + TEST_CHECK(env->query_use(UseFlagName("foo"), &pde)); + TEST_CHECK(! env->query_use(UseFlagName("foofoo"), &pde)); + TEST_CHECK(env->query_use(UseFlagName("moo"), &pde)); + + TEST_CHECK(env->query_use(UseFlagName("more_exp_one"), &pde)); + TEST_CHECK(env->query_use(UseFlagName("exp_two"), &pde)); + TEST_CHECK(env->query_use(UseFlagName("exp_one"), &pde)); + TEST_CHECK(env->query_use(UseFlagName("third_exp_one"), &pde)); + TEST_CHECK(! env->query_use(UseFlagName("third_exp_two"), &pde)); + + PackageDatabaseEntry f(QualifiedPackageName("cat-one/pkg-two"), VersionSpec("3"), RepositoryName("foo")); + TEST_CHECK(env->query_use(UseFlagName("third_exp_one"), &f)); + TEST_CHECK(env->query_use(UseFlagName("third_exp_two"), &f)); + } + } default_environment_use_test; + + struct TestDefaultEnvironmentUseMinusStar : TestCase + { + TestDefaultEnvironmentUseMinusStar() : TestCase("use -*") { } + + void run() + { + setenv("PALUDIS_HOME", stringify(FSEntry::cwd() / "default_environment_TEST_dir" / "home2").c_str(), 1); + unsetenv("PALUDIS_SKIP_CONFIG"); + DefaultConfig::destroy_instance(); + DefaultEnvironment::destroy_instance(); + + Environment * env(DefaultEnvironment::get_instance()); + + TEST_CHECK(env->query_use(UseFlagName("foo"), 0)); + TEST_CHECK(! env->query_use(UseFlagName("foofoo"), 0)); + + PackageDatabaseEntry pde(QualifiedPackageName("cat-one/pkg-one"), VersionSpec("1"), RepositoryName("foo")); + TEST_CHECK(env->query_use(UseFlagName("foo"), &pde)); + TEST_CHECK(! env->query_use(UseFlagName("foofoo"), &pde)); + TEST_CHECK(! env->query_use(UseFlagName("moo"), &pde)); + + TEST_CHECK(env->query_use(UseFlagName("more_exp_one"), &pde)); + TEST_CHECK(env->query_use(UseFlagName("exp_two"), &pde)); + TEST_CHECK(! env->query_use(UseFlagName("exp_one"), &pde)); + TEST_CHECK(env->query_use(UseFlagName("third_exp_one"), &pde)); + TEST_CHECK(! env->query_use(UseFlagName("third_exp_two"), &pde)); + + PackageDatabaseEntry f(QualifiedPackageName("cat-one/pkg-two"), VersionSpec("3"), RepositoryName("foo")); + TEST_CHECK(! env->query_use(UseFlagName("third_exp_one"), &f)); + TEST_CHECK(env->query_use(UseFlagName("third_exp_two"), &f)); + } + } default_environment_use_test_minus_star; + + struct TestDefaultEnvironmentUseMinusPartialStar : TestCase + { + TestDefaultEnvironmentUseMinusPartialStar() : TestCase("use -* partial") { } + + void run() + { + setenv("PALUDIS_HOME", stringify(FSEntry::cwd() / "default_environment_TEST_dir" / "home3").c_str(), 1); + unsetenv("PALUDIS_SKIP_CONFIG"); + DefaultConfig::destroy_instance(); + DefaultEnvironment::destroy_instance(); + + Environment * env(DefaultEnvironment::get_instance()); + + TEST_CHECK(env->query_use(UseFlagName("foo"), 0)); + TEST_CHECK(! env->query_use(UseFlagName("foofoo"), 0)); + + PackageDatabaseEntry pde(QualifiedPackageName("cat-one/pkg-one"), VersionSpec("1"), RepositoryName("foo")); + TEST_CHECK(env->query_use(UseFlagName("foo"), &pde)); + TEST_CHECK(! env->query_use(UseFlagName("foofoo"), &pde)); + TEST_CHECK(env->query_use(UseFlagName("moo"), &pde)); + + TEST_CHECK(env->query_use(UseFlagName("more_exp_one"), &pde)); + TEST_CHECK(env->query_use(UseFlagName("exp_two"), &pde)); + TEST_CHECK(! env->query_use(UseFlagName("exp_one"), &pde)); + TEST_CHECK(env->query_use(UseFlagName("third_exp_one"), &pde)); + TEST_CHECK(! env->query_use(UseFlagName("third_exp_two"), &pde)); + + PackageDatabaseEntry f(QualifiedPackageName("cat-one/pkg-two"), VersionSpec("3"), RepositoryName("foo")); + TEST_CHECK(! env->query_use(UseFlagName("third_exp_one"), &f)); + TEST_CHECK(env->query_use(UseFlagName("third_exp_two"), &f)); + } + } default_environment_use_test_minus_star_partial; +} + diff --git a/0.8.0/paludis/environment/default/default_environment_TEST_cleanup.sh b/0.8.0/paludis/environment/default/default_environment_TEST_cleanup.sh new file mode 100755 index 000000000..3cd5c8db3 --- /dev/null +++ b/0.8.0/paludis/environment/default/default_environment_TEST_cleanup.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# vim: set ft=sh sw=4 sts=4 et : + +if [ -d default_environment_TEST_dir ] ; then + rm -fr default_environment_TEST_dir +else + true +fi + + + diff --git a/0.8.0/paludis/environment/default/default_environment_TEST_setup.sh b/0.8.0/paludis/environment/default/default_environment_TEST_setup.sh new file mode 100755 index 000000000..bb19c8a5b --- /dev/null +++ b/0.8.0/paludis/environment/default/default_environment_TEST_setup.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# vim: set ft=sh sw=4 sts=4 et : + +mkdir default_environment_TEST_dir || exit 2 +cd default_environment_TEST_dir || exit 3 + +mkdir -p repo/{profile,profiles,cat-one/pkg-one} +cat <<END > repo/profiles/repo_name +foo +END +cat <<END > repo/profiles/categories +cat-one +END +cat <<END > repo/profile/make.defaults +ARCH="foo" +USE="moo" +USE_EXPAND="EXP MORE_EXP THIRD_EXP" +EXP="one" +MORE_EXP="one" +THIRD_EXP="one" +END + +mkdir -p home1/.paludis/repositories +cat <<END > home1/.paludis/use.conf +* foo bar baz -fnord +* EXP: two +>=cat-one/pkg-two-2 THIRD_EXP: two +END +cat <<END > home1/.paludis/keywords.conf +* keyword +END +cat <<END > home1/.paludis/licenses.conf +* keyword +END +cat <<END > home1/.paludis/repositories/foo.conf +format = portage +location = `pwd`/repo +profiles = `pwd`/repo/profile +cache = /var/empty +END + +mkdir -p home2/.paludis/repositories +cat <<END > home2/.paludis/use.conf +* -* foo bar baz -fnord +* EXP: -* two +>=cat-one/pkg-two-2 THIRD_EXP: -* two +END +cat <<END > home2/.paludis/keywords.conf +* keyword +END +cat <<END > home2/.paludis/licenses.conf +* * +END +cat <<END > home2/.paludis/repositories/foo.conf +format = portage +location = `pwd`/repo +profiles = `pwd`/repo/profile +cache = /var/empty +END + +mkdir -p home3/.paludis/repositories +cat <<END > home3/.paludis/use.conf +* foo bar baz -fnord +* EXP: -* two +>=cat-one/pkg-two-2 THIRD_EXP: -* two +END +cat <<END > home3/.paludis/keywords.conf +* keyword +END +cat <<END > home3/.paludis/licenses.conf +* * +END +cat <<END > home3/.paludis/repositories/foo.conf +format = portage +location = `pwd`/repo +profiles = `pwd`/repo/profile +cache = /var/empty +END + + diff --git a/0.8.0/paludis/environment/no_config/Makefile.am b/0.8.0/paludis/environment/no_config/Makefile.am new file mode 100644 index 000000000..4c4503140 --- /dev/null +++ b/0.8.0/paludis/environment/no_config/Makefile.am @@ -0,0 +1,41 @@ +CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda ihateautomake.cc ihateautomake.o +DISTCLEANFILES = no_config_environment-sr.hh no_config_environment-sr.cc +MAINTAINERCLEANFILES = Makefile.in +AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@ +DEFS= \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DDATADIR=\"$(datadir)\" \ + -DLIBDIR=\"$(libdir)\" + +libpaludisnoconfigenvironment_la_SOURCES = \ + no_config_environment.cc no_config_environment.hh + +libpaludisnoconfigenvironment_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0 +libpaludisnoconfigenvironment_la_LIBADD = \ + $(top_builddir)/paludis/util/libpaludisutil.la \ + $(top_builddir)/paludis/libpaludis.la \ + $(top_builddir)/paludis/repositories/portage/libpaludisportagerepository.la + +lib_LTLIBRARIES = libpaludisnoconfigenvironment.la +paludis_environment_no_config_includedir = $(includedir)/paludis/environment/no_config +paludis_environment_no_config_include_HEADERS = \ + no_config_environment.hh \ + no_config_environment-sr.hh + +EXTRA_DIST = \ + no_config_environment-sr.hh \ + no_config_environment-sr.cc \ + no_config_environment.sr + +BUILT_SOURCES = \ + no_config_environment-sr.hh \ + no_config_environment-sr.cc + +no_config_environment-sr.hh : no_config_environment.sr $(top_srcdir)/misc/make_sr.bash + $(top_srcdir)/misc/make_sr.bash --header $(srcdir)/no_config_environment.sr > $@ + +no_config_environment-sr.cc : no_config_environment.sr $(top_srcdir)/misc/make_sr.bash + $(top_srcdir)/misc/make_sr.bash --source $(srcdir)/no_config_environment.sr > $@ + + diff --git a/0.8.0/paludis/environment/no_config/no_config_environment.cc b/0.8.0/paludis/environment/no_config/no_config_environment.cc new file mode 100644 index 000000000..b9022fab7 --- /dev/null +++ b/0.8.0/paludis/environment/no_config/no_config_environment.cc @@ -0,0 +1,197 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * 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 "no_config_environment.hh" +#include <paludis/util/collection_concrete.hh> +#include <paludis/util/tokeniser.hh> +#include <paludis/util/log.hh> +#include <paludis/repositories/portage/portage_repository.hh> +#include <paludis/config_file.hh> +#include <set> + +using namespace paludis; + +#include <paludis/environment/no_config/no_config_environment-sr.cc> + +namespace paludis +{ + template<> + struct Implementation<NoConfigEnvironment> : + InternalCounted<Implementation<NoConfigEnvironment> > + { + const FSEntry top_level_dir; + bool accept_unstable; + std::set<KeywordName> accepted_keywords; + std::list<NoConfigEnvironmentProfilesDescLine> profiles; + + Implementation(Environment * const env, const NoConfigEnvironmentParams & params) : + top_level_dir(params.repository_dir), + accept_unstable(params.accept_unstable) + { + Context context("When initialising NoConfigEnvironment at '" + stringify(params.repository_dir) + "':"); + + try + { + LineConfigFile profiles_desc(params.repository_dir / "profiles" / "profiles.desc"); + for (LineConfigFile::Iterator line(profiles_desc.begin()), line_end(profiles_desc.end()) ; + line != line_end ; ++line) + { + std::vector<std::string> tokens; + WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens)); + + if (tokens.size() != 3) + { + Log::get_instance()->message(ll_warning, lc_context, "Skipping invalid line '" + + *line + "'"); + continue; + } + + profiles.push_back(NoConfigEnvironmentProfilesDescLine::create() + .path(params.repository_dir / "profiles" / tokens.at(1)) + .status(tokens.at(2)) + .arch(tokens.at(0)) + .db(PackageDatabase::Pointer(new PackageDatabase(env)))); + } + } + catch (const ConfigFileError & e) + { + Log::get_instance()->message(ll_warning, lc_context, "Could not load profiles.desc due to exception '" + + e.message() + "' (" + e.what() + ")"); + } + + if (profiles.empty()) + profiles.push_back(NoConfigEnvironmentProfilesDescLine::create() + .path(params.repository_dir / "profiles" / "base") + .status("default") + .arch("default") + .db(PackageDatabase::Pointer(new PackageDatabase(env)))); + + for (std::list<NoConfigEnvironmentProfilesDescLine>::iterator + p(profiles.begin()), p_end(profiles.end()) ; p != p_end ; ++p) + { + AssociativeCollection<std::string, std::string>::Pointer keys( + new AssociativeCollection<std::string, std::string>::Concrete); + + keys->insert("format", "portage"); + keys->insert("location", stringify(params.repository_dir)); + keys->insert("profiles", stringify(p->path)); + + p->db->add_repository(RepositoryMaker::get_instance()->find_maker("portage")(env, + p->db.raw_pointer(), keys)); + p->db->add_repository(RepositoryMaker::get_instance()->find_maker("virtuals")(env, + p->db.raw_pointer(), AssociativeCollection<std::string, std::string>::Pointer(0))); + } + } + }; + + /* This goat is for Dave Wickham */ +} + +NoConfigEnvironment::NoConfigEnvironment(const NoConfigEnvironmentParams & params) : + PrivateImplementationPattern<NoConfigEnvironment>( + new Implementation<NoConfigEnvironment>(this, params)), + Environment(_imp->profiles.begin()->db) +{ + /* do this to load accepted_keywords etc */ + set_profile(ProfilesIterator(_imp->profiles.begin())); +} + +NoConfigEnvironment::~NoConfigEnvironment() +{ +} + +std::string +NoConfigEnvironment::paludis_command() const +{ + return "false"; +} + +FSEntry +NoConfigEnvironment::main_repository_dir() const +{ + return _imp->top_level_dir; +} + +void +NoConfigEnvironment::set_profile(const NoConfigEnvironment::ProfilesIterator & i) +{ + change_package_database(i->db); + + _imp->accepted_keywords.clear(); + _imp->accepted_keywords.insert(KeywordName("*")); + _imp->accepted_keywords.insert(KeywordName(i->arch)); + if (_imp->accept_unstable) + _imp->accepted_keywords.insert(KeywordName("~" + i->arch)); +} + +void +NoConfigEnvironment::set_profile(const FSEntry & location) +{ + Context context("When setting NoConfigEnvironment profile to '" + stringify(location) + "':"); + + for (ProfilesIterator i(begin_profiles()), i_end(end_profiles()) ; i != i_end ; ++i) + if (i->path == location) + { + set_profile(i); + return; + } + + Log::get_instance()->message(ll_warning, lc_context, "No profiles.desc entry found, faking it"); + + PackageDatabase::Pointer db(new PackageDatabase(this)); + AssociativeCollection<std::string, std::string>::Pointer keys( + new AssociativeCollection<std::string, std::string>::Concrete); + + keys->insert("format", "portage"); + keys->insert("location", stringify(_imp->top_level_dir)); + keys->insert("profiles", stringify(location)); + + PortageRepository::Pointer p(RepositoryMaker::get_instance()->find_maker("portage")(this, + db.raw_pointer(), keys)); + db->add_repository(RepositoryMaker::get_instance()->find_maker("virtuals")(this, + db.raw_pointer(), AssociativeCollection<std::string, std::string>::Pointer(0))); + db->add_repository(p); + + _imp->accepted_keywords.clear(); + _imp->accepted_keywords.insert(KeywordName("*")); + _imp->accepted_keywords.insert(KeywordName(p->profile_variable("ARCH"))); + if (_imp->accept_unstable) + _imp->accepted_keywords.insert(KeywordName("~" + p->profile_variable("ARCH"))); + + change_package_database(db); +} + +bool +NoConfigEnvironment::accept_keyword(const KeywordName & k, const PackageDatabaseEntry * const) const +{ + return _imp->accepted_keywords.end() != _imp->accepted_keywords.find(k); +} + +NoConfigEnvironment::ProfilesIterator +NoConfigEnvironment::begin_profiles() const +{ + return ProfilesIterator(_imp->profiles.begin()); +} + +NoConfigEnvironment::ProfilesIterator +NoConfigEnvironment::end_profiles() const +{ + return ProfilesIterator(_imp->profiles.end()); +} + diff --git a/0.8.0/paludis/environment/no_config/no_config_environment.hh b/0.8.0/paludis/environment/no_config/no_config_environment.hh new file mode 100644 index 000000000..37837f176 --- /dev/null +++ b/0.8.0/paludis/environment/no_config/no_config_environment.hh @@ -0,0 +1,57 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * 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_ENVIRONMENT_NO_CONFIG_NO_CONFIG_ENVIRONMENT_HH +#define PALUDIS_GUARD_PALUDIS_ENVIRONMENT_NO_CONFIG_NO_CONFIG_ENVIRONMENT_HH 1 + +#include <paludis/environment.hh> +#include <paludis/util/fs_entry.hh> +#include <paludis/util/private_implementation_pattern.hh> +#include <libwrapiter/libwrapiter_forward_iterator.hh> + +namespace paludis +{ +#include <paludis/environment/no_config/no_config_environment-sr.hh> + + class PALUDIS_VISIBLE NoConfigEnvironment : + private PrivateImplementationPattern<NoConfigEnvironment>, + public Environment + { + public: + NoConfigEnvironment(const NoConfigEnvironmentParams & params); + + virtual ~NoConfigEnvironment(); + + virtual std::string paludis_command() const; + + FSEntry main_repository_dir() const; + + virtual bool accept_keyword(const KeywordName &, const PackageDatabaseEntry * const) const; + + typedef libwrapiter::ForwardIterator<NoConfigEnvironment, const NoConfigEnvironmentProfilesDescLine> ProfilesIterator; + ProfilesIterator begin_profiles() const; + ProfilesIterator end_profiles() const; + + void set_profile(const FSEntry & location); + void set_profile(const ProfilesIterator & iter); + + }; +} + +#endif diff --git a/0.8.0/paludis/environment/no_config/no_config_environment.sr b/0.8.0/paludis/environment/no_config/no_config_environment.sr new file mode 100644 index 000000000..0db14bbef --- /dev/null +++ b/0.8.0/paludis/environment/no_config/no_config_environment.sr @@ -0,0 +1,19 @@ +#!/bin/bash +# vim: set sw=4 sts=4 et : + +make_class_NoConfigEnvironmentParams() +{ + key repository_dir "FSEntry" + key accept_unstable bool + allow_named_args +} + +make_class_NoConfigEnvironmentProfilesDescLine() +{ + key path FSEntry + key arch std::string + key status std::string + key db PackageDatabase::Pointer + allow_named_args +} + diff --git a/0.8.0/paludis/environment/test/Makefile.am b/0.8.0/paludis/environment/test/Makefile.am new file mode 100644 index 000000000..b48bf1b1d --- /dev/null +++ b/0.8.0/paludis/environment/test/Makefile.am @@ -0,0 +1,21 @@ +CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda ihateautomake.cc ihateautomake.o +MAINTAINERCLEANFILES = Makefile.in +AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@ +DEFS= \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DDATADIR=\"$(datadir)\" \ + -DLIBDIR=\"$(libdir)\" + +libpaludistestenvironment_la_SOURCES = \ + test_environment.cc test_environment.hh + +libpaludistestenvironment_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0 +libpaludistestenvironment_la_LIBADD = \ + $(top_builddir)/paludis/util/libpaludisutil.la \ + $(top_builddir)/paludis/libpaludis.la + +lib_LTLIBRARIES = libpaludistestenvironment.la +paludis_environment_test_includedir = $(includedir)/paludis/environment/test +paludis_environment_test_include_HEADERS = test_environment.hh + diff --git a/0.8.0/paludis/environment/test/test_environment.cc b/0.8.0/paludis/environment/test/test_environment.cc new file mode 100644 index 000000000..7e1ce46dc --- /dev/null +++ b/0.8.0/paludis/environment/test/test_environment.cc @@ -0,0 +1,85 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * 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/environment/test/test_environment.hh> +#include <paludis/util/collection_concrete.hh> +#include <map> +#include <string> + +/** \file + * Implementation of TestEnvironment. + * + * \ingroup grptestenvironment + */ + +using namespace paludis; + +TestEnvironment::TestEnvironment() : + Environment(PackageDatabase::Pointer(new PackageDatabase(this))) +{ +} + +bool +TestEnvironment::query_use(const UseFlagName & u, const PackageDatabaseEntry *) const +{ + return (std::string::npos != u.data().find("enabled")); +} + +bool +TestEnvironment::accept_keyword(const KeywordName & k, const PackageDatabaseEntry * const) const +{ + return k == KeywordName("test"); +} + +bool +TestEnvironment::accept_license(const std::string &, const PackageDatabaseEntry * const) const +{ + return true; +} + +bool +TestEnvironment::query_user_masks(const PackageDatabaseEntry &) const +{ + return false; +} + +bool +TestEnvironment::query_user_unmasks(const PackageDatabaseEntry &) const +{ + return false; +} + +namespace +{ + static const std::multimap<std::string, std::string> test_environment_mirrors; +} + +TestEnvironment::MirrorIterator +TestEnvironment::begin_mirrors(const std::string &) const +{ + return MirrorIterator(test_environment_mirrors.begin()); +} + +TestEnvironment::MirrorIterator +TestEnvironment::end_mirrors(const std::string &) const +{ + return MirrorIterator(test_environment_mirrors.end()); +} + + diff --git a/0.8.0/paludis/environment/test/test_environment.hh b/0.8.0/paludis/environment/test/test_environment.hh new file mode 100644 index 000000000..d9b1178fc --- /dev/null +++ b/0.8.0/paludis/environment/test/test_environment.hh @@ -0,0 +1,84 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * + * 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_TEST_ENVIRONMENT_HH +#define PALUDIS_GUARD_PALUDIS_TEST_ENVIRONMENT_HH 1 + +#include <paludis/package_database_entry.hh> +#include <paludis/environment.hh> + +/** \file + * Declarations for the TestEnvironment class. + * + * \ingroup grptestenvironment + */ + +namespace paludis +{ + /** + * A TestEnvironment is an environment used during testing that lets us + * control all the options rather than reading them from configuration + * files. + * + * \ingroup grptestenvironment + */ + class PALUDIS_VISIBLE TestEnvironment : public Environment + { + public: + /** + * Constructor. + */ + TestEnvironment(); + + virtual bool query_use(const UseFlagName &, const PackageDatabaseEntry *) const; + + virtual bool accept_keyword(const KeywordName &, const PackageDatabaseEntry * const) const; + + virtual bool query_user_masks(const PackageDatabaseEntry &) const; + + virtual bool query_user_unmasks(const PackageDatabaseEntry &) const; + + virtual bool accept_license(const std::string &, const PackageDatabaseEntry * const) const; + + virtual std::string bashrc_files() const + { + return ""; + } + + virtual std::string hook_dirs() const + { + return ""; + } + + virtual std::string paludis_command() const + { + return "false"; + } + + virtual void perform_hook(const Hook &) const + { + } + + virtual MirrorIterator begin_mirrors(const std::string &) const; + + virtual MirrorIterator end_mirrors(const std::string &) const; + }; +} + +#endif |