aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Danny van Dyk <dvandyk@exherbo.org> 2006-12-22 12:43:11 +0000
committerAvatar Danny van Dyk <dvandyk@exherbo.org> 2006-12-22 12:43:11 +0000
commit60e64edbf8b40c6157666c372e54ba719f868839 (patch)
treead3b995d440c45db31c17c2cc2d6ed5a4433500d
parent93ef86c8467a4a373ec349999db3b5f3ed382591 (diff)
downloadpaludis-60e64edbf8b40c6157666c372e54ba719f868839.tar.gz
paludis-60e64edbf8b40c6157666c372e54ba719f868839.tar.xz
Add contrarius and all necessary prerequisites.
-rw-r--r--configure.ac1
-rw-r--r--paludis/environment/default/default_config.cc27
-rw-r--r--paludis/environment/default/default_config.hh17
-rw-r--r--paludis/environment/default/default_environment.cc35
-rw-r--r--paludis/files.m41
-rw-r--r--paludis/host_tuple_name.cc237
-rw-r--r--paludis/host_tuple_name.hh244
-rw-r--r--paludis/host_tuple_name.sr27
-rw-r--r--paludis/host_tuple_name_TEST.cc225
-rw-r--r--paludis/tasks/Makefile.am17
-rw-r--r--paludis/tasks/stage_builder_task.cc119
-rw-r--r--paludis/tasks/stage_builder_task.hh142
-rw-r--r--paludis/tasks/stage_options.sr19
-rw-r--r--src/Makefile.am2
-rw-r--r--src/colour.hh6
-rw-r--r--src/contrarius/Makefile.am80
-rw-r--r--src/contrarius/command_line.cc105
-rw-r--r--src/contrarius/command_line.hh147
-rw-r--r--src/contrarius/contrarius.cc211
-rw-r--r--src/contrarius/install.cc373
-rw-r--r--src/contrarius/install.hh34
-rw-r--r--src/contrarius/man_contrarius.cc37
-rw-r--r--src/contrarius/stage.cc183
-rw-r--r--src/contrarius/stage.hh174
-rw-r--r--src/contrarius/stage_builder.cc90
-rw-r--r--src/contrarius/stage_builder.hh48
26 files changed, 2599 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index bb5bf85..efec8ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -767,6 +767,7 @@ AC_OUTPUT(
ruby/Makefile
ruby/demos/Makefile
src/Makefile
+ src/contrarius/Makefile
src/paludis/Makefile
src/gtkpaludis/Makefile
src/gtkpaludis/cellrendererbutton/Makefile
diff --git a/paludis/environment/default/default_config.cc b/paludis/environment/default/default_config.cc
index 5036f0f..04ff3b2 100644
--- a/paludis/environment/default/default_config.cc
+++ b/paludis/environment/default/default_config.cc
@@ -107,6 +107,8 @@ namespace paludis
std::multimap<std::string, std::string> mirrors;
+ std::vector<UseConfigEntry> forced_use_config;
+
Implementation();
};
@@ -484,6 +486,31 @@ DefaultConfig::~DefaultConfig()
}
void
+DefaultConfig::add_forced_use_config(const UseConfigEntry & e)
+{
+ _imp->forced_use_config.push_back(e);
+}
+
+void
+DefaultConfig::clear_forced_use_config()
+{
+ _imp->forced_use_config.clear();
+}
+
+DefaultConfig::UseConfigIterator
+DefaultConfig::begin_forced_use_config() const
+{
+ return UseConfigIterator(_imp->forced_use_config.begin());
+}
+
+
+DefaultConfig::UseConfigIterator
+DefaultConfig::end_forced_use_config() const
+{
+ return UseConfigIterator(_imp->forced_use_config.end());
+}
+
+void
DefaultConfig::set_config_suffix(const std::string & s)
{
if (! Implementation<DefaultConfig>::config_suffix_can_be_set)
diff --git a/paludis/environment/default/default_config.hh b/paludis/environment/default/default_config.hh
index 88af309..4c273fe 100644
--- a/paludis/environment/default/default_config.hh
+++ b/paludis/environment/default/default_config.hh
@@ -191,6 +191,23 @@ namespace paludis
///\}
/**
+ * Add a forced USE flag to this configuration.
+ */
+ void add_forced_use_config(const UseConfigEntry & e);
+
+ /**
+ * Clear all forced USE flags.
+ */
+ void clear_forced_use_config();
+
+ ///\name Iterate over our forced USE flags
+ ///\{
+ UseConfigIterator begin_forced_use_config() const;
+ UseConfigIterator end_forced_use_config() const;
+ ///\}
+
+
+ /**
* Our bashrc files.
*/
std::string bashrc_files() const;
diff --git a/paludis/environment/default/default_environment.cc b/paludis/environment/default/default_environment.cc
index acc94f1..fd0376f 100644
--- a/paludis/environment/default/default_environment.cc
+++ b/paludis/environment/default/default_environment.cc
@@ -68,6 +68,25 @@ DefaultEnvironment::query_use(const UseFlagName & f, const PackageDatabaseEntry
return true;
}
+ /* check use: forced use config */
+ for (DefaultConfig::UseConfigIterator
+ u(DefaultConfig::get_instance()->begin_forced_use_config()),
+ u_end(DefaultConfig::get_instance()->end_forced_use_config()) ;
+ u != u_end ; ++u)
+ {
+ if (u->dep_atom)
+ continue;
+
+ if (u->flag_name != f)
+ continue;
+
+ Log::get_instance()->message(ll_debug, lc_no_context, "Forced use flag: "
+ + stringify(u->flag_name) + ", state: "
+ + ((u->flag_state == use_enabled) ? "enabled" : "disabled"));
+
+ return u->flag_state == use_enabled;
+ }
+
/* check use: per package user config */
if (e)
{
@@ -535,11 +554,27 @@ DefaultEnvironment::known_use_expand_names(const UseFlagName & prefix, const Pac
result->insert(i->first);
if (pde)
+ {
+ for (DefaultConfig::UseConfigIterator i(DefaultConfig::get_instance()->begin_forced_use_config()),
+ i_end(DefaultConfig::get_instance()->end_forced_use_config()) ; i != i_end ; ++i)
+ {
+ if (! i->dep_atom)
+ continue;
+
+ if (! match_package(this, *i->dep_atom, *pde))
+ continue;
+
+ 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);
+ }
+
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")) + ") -> ("
diff --git a/paludis/files.m4 b/paludis/files.m4
index 08dac76..f9dd615 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -19,6 +19,7 @@ add(`ebin', `hh', `cc', `sr')
add(`ebuild', `hh', `cc', `sr')
add(`environment', `hh', `cc')
add(`hashed_containers', `hhx', `cc', `test')
+add(`host_tuple_name', `hh', `cc', `sr', `test')
add(`mask_reasons', `hh', `cc')
add(`match_package', `hh', `cc')
add(`name', `hh', `cc', `test', `sr')
diff --git a/paludis/host_tuple_name.cc b/paludis/host_tuple_name.cc
new file mode 100644
index 0000000..0a24b52
--- /dev/null
+++ b/paludis/host_tuple_name.cc
@@ -0,0 +1,237 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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/host_tuple_name.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/compare.hh>
+#include <paludis/util/tokeniser.hh>
+#include <vector>
+#include <ostream>
+
+/** \file
+ * Implementation of configuration_name.hh things.
+ *
+ * \ingroup grpnames
+ */
+
+using namespace paludis;
+
+#include <paludis/host_tuple_name-sr.cc>
+
+HostTupleNameError::HostTupleNameError(const std::string & name) throw () :
+ NameError(name, "host tuple name")
+{
+}
+
+HostTupleNameError::HostTupleNameError(const std::string & name,
+ const std::string & type) throw () :
+ NameError(name, type)
+{
+}
+
+HostTupleName::HostTupleName(const std::string & s) :
+ architecture("architecture"),
+ manufacturer("manufacturer"),
+ kernel("kernel"),
+ userland("userland")
+{
+ Context c("When creating a HostTupleName from '" + s + "':");
+
+ Tokeniser<delim_kind::AnyOfTag, delim_mode::DelimiterTag> tokeniser("-");
+ std::vector<std::string> tokens;
+
+ tokeniser.tokenise(s, std::back_inserter(tokens));
+ switch (tokens.size())
+ {
+ case 2: // Type 'arch'-'userland', i.e. 'spu-elf'.
+ architecture = ArchitectureNamePart(tokens[0]);
+ manufacturer = ManufacturerNamePart("");
+ kernel = KernelNamePart("");
+ userland = UserlandNamePart(tokens[1]);
+
+ break;
+
+ case 3: /*
+ * Type 'arch'-'manufacturer'-'os', i.e. 'i386-unknown-freebsd6.0'.
+ * Let's duplicate the 'os' field into kernel and userland.
+ */
+ architecture = ArchitectureNamePart(tokens[0]);
+ manufacturer = ManufacturerNamePart(tokens[1]);
+ kernel = KernelNamePart(tokens[2]);
+ userland = UserlandNamePart(tokens[2]);
+
+ break;
+
+ case 4: // Type full
+ architecture = ArchitectureNamePart(tokens[0]);
+ manufacturer = ManufacturerNamePart(tokens[1]);
+ kernel = KernelNamePart(tokens[2]);
+ userland = UserlandNamePart(tokens[3]);
+
+ break;
+
+ default:
+ throw HostTupleNameError(s);
+ }
+}
+
+std::ostream &
+paludis::operator<< (std::ostream & s, const HostTupleName & c)
+{
+ s << c.architecture;
+ if (! c.manufacturer.data().empty())
+ s << "-" << c.manufacturer;
+ if (! c.kernel.data().empty())
+ s << "-" << c.kernel;
+ s << "-" << c.userland;
+ return s;
+}
+
+void
+ArchitectureNamePartValidator::validate(const std::string & s)
+{
+ static const std::string allowed_chars(
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789_.");
+ // '.' is included, as 'HPPA1.x' is a valid ArchitectureNamePart.
+
+ do
+ {
+ if (s.empty())
+ break;
+
+ if ('-' == s.at(0))
+ break;
+
+ if (std::string::npos != s.find_first_not_of(allowed_chars))
+ break;
+
+ return;
+
+ } while (false);
+
+ Context c("When validating architecture name '" + s + "':");
+
+ throw ArchitectureNamePartError(s);
+}
+
+ArchitectureNamePartError::ArchitectureNamePartError(const std::string & name) throw () :
+ HostTupleNameError(name, "architecture name part")
+{
+}
+
+void
+ManufacturerNamePartValidator::validate(const std::string & s)
+{
+ static const std::string allowed_chars(
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789_");
+
+ do
+ {
+ if (s.empty())
+ return;
+
+ if ('-' == s.at(0))
+ break;
+
+ if (std::string::npos != s.find_first_not_of(allowed_chars))
+ break;
+
+ return;
+
+ } while (false);
+
+ Context c("When validating manufacturer name '" + s + "':");
+
+ throw ManufacturerNamePartError(s);
+}
+
+ManufacturerNamePartError::ManufacturerNamePartError(const std::string & name) throw () :
+ HostTupleNameError(name, "manufacturer name part")
+{
+}
+
+void
+KernelNamePartValidator::validate(const std::string & s)
+{
+ static const std::string allowed_chars(
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789_.");
+
+ do
+ {
+ if (s.empty())
+ return;
+
+ if ('-' == s.at(0))
+ break;
+
+ if (std::string::npos != s.find_first_not_of(allowed_chars))
+ break;
+
+ return;
+
+ } while (false);
+
+ Context c("When validating kernel name '" + s + "':");
+
+ throw KernelNamePartError(s);
+}
+
+KernelNamePartError::KernelNamePartError(const std::string & name) throw () :
+ HostTupleNameError(name, "kernel name part")
+{
+}
+
+void
+UserlandNamePartValidator::validate(const std::string & s)
+{
+ static const std::string allowed_chars(
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789_.");
+
+ do
+ {
+ if (s.empty())
+ break;
+
+ if ('-' == s.at(0))
+ break;
+
+ if (std::string::npos != s.find_first_not_of(allowed_chars))
+ break;
+
+ return;
+
+ } while (false);
+
+ Context c("When validating manufacturer name '" + s + "':");
+
+ throw UserlandNamePartError(s);
+}
+
+UserlandNamePartError::UserlandNamePartError(const std::string & name) throw () :
+ HostTupleNameError(name, "userland name part")
+{
+}
diff --git a/paludis/host_tuple_name.hh b/paludis/host_tuple_name.hh
new file mode 100644
index 0000000..e9796ac
--- /dev/null
+++ b/paludis/host_tuple_name.hh
@@ -0,0 +1,244 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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_HOST_TUPLE_NAME_HH
+#define PALUDIS_GUARD_PALUDIS_HOST_TUPLE_NAME_HH 1
+
+#include <paludis/util/exception.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/sr.hh>
+#include <paludis/util/validated.hh>
+
+#include <string>
+#include <iosfwd>
+
+/** \file
+ * Declarations for various Name classes.
+ *
+ * \ingroup grpnames
+ * \ingroup grpconfigurationname
+ */
+
+namespace paludis
+{
+ /**
+ * A HostTupleNameError is thrown if an invalid value is assigned to
+ * an HostTupleName.
+ *
+ * \ingroup grpnames
+ * \ingroup grpconfigurationname
+ * \ingroup grpexceptions
+ */
+ class HostTupleNameError : public NameError
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ HostTupleNameError(const std::string & name) throw ();
+
+ HostTupleNameError(const std::string & name,
+ const std::string & type) throw ();
+ };
+
+ /**
+ * An ArchitectureNamePartError is thrown if an invalid value is assigned to
+ * an ArchitectureNamePart.
+ *
+ * \ingroup grpnames
+ * \ingroup grpconfigurationname
+ * \ingroup grpexceptions
+ */
+ class ArchitectureNamePartError : public HostTupleNameError
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ ArchitectureNamePartError(const std::string & name) throw ();
+ };
+
+ /**
+ * An ArchitectureNamePartValidator handles validation rules for the value
+ * of an ArchitectureNamePart.
+ *
+ * \ingroup grpnames
+ * \ingroup configurationname
+ */
+ struct ArchitectureNamePartValidator :
+ private InstantiationPolicy<ArchitectureNamePartValidator, instantiation_method::NonInstantiableTag>
+ {
+ /**
+ * If the parameter is not a valid value for an ArchitectureNamePart,
+ * throw an ArchitectureNamePartError.
+ */
+ static void validate(const std::string &);
+ };
+
+ /**
+ * An ArchitectureNamePart holds a std::string that is a valid name for the
+ * architecture part of a HostTupleName.
+ *
+ * \ingroup grpnames
+ * \ingroup grpconfigurationname
+ */
+ typedef Validated<std::string, ArchitectureNamePartValidator> ArchitectureNamePart;
+
+ /**
+ * An ManufacturerNamePartError is thrown if an invalid value is assigned to
+ * an ManufacturerNamePart.
+ *
+ * \ingroup grpnames
+ * \ingroup grpconfigurationname
+ * \ingroup grpexceptions
+ */
+ class ManufacturerNamePartError : public HostTupleNameError
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ ManufacturerNamePartError(const std::string & name) throw ();
+ };
+
+ /**
+ * An ManufacturerNamePartValidator handles validation rules for the value
+ * of an ManufacturerNamePart.
+ *
+ * \ingroup grpnames
+ * \ingroup configurationname
+ */
+ struct ManufacturerNamePartValidator :
+ private InstantiationPolicy<ManufacturerNamePartValidator, instantiation_method::NonInstantiableTag>
+ {
+ /**
+ * If the parameter is not a valid value for an ManufacturerNamePart,
+ * throw an ManufacturerNamePartError.
+ */
+ static void validate(const std::string &);
+ };
+
+ /**
+ * An ManufacturerNamePart holds a std::string that is a valid name for the
+ * architecture part of a HostTupleName.
+ *
+ * \ingroup grpnames
+ * \ingroup grpconfigurationname
+ */
+ typedef Validated<std::string, ManufacturerNamePartValidator> ManufacturerNamePart;
+
+ /**
+ * An KernelNamePartError is thrown if an invalid value is assigned to
+ * an KernelNamePart.
+ *
+ * \ingroup grpnames
+ * \ingroup grpconfigurationname
+ * \ingroup grpexceptions
+ */
+ class KernelNamePartError : public HostTupleNameError
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ KernelNamePartError(const std::string & name) throw ();
+ };
+
+ /**
+ * An KernelNamePartValidator handles validation rules for the value
+ * of an KernelNamePart.
+ *
+ * \ingroup grpnames
+ * \ingroup configurationname
+ */
+ struct KernelNamePartValidator :
+ private InstantiationPolicy<KernelNamePartValidator, instantiation_method::NonInstantiableTag>
+ {
+ /**
+ * If the parameter is not a valid value for an KernelNamePart,
+ * throw an KernelNamePartError.
+ */
+ static void validate(const std::string &);
+ };
+
+ /**
+ * An KernelNamePart holds a std::string that is a valid name for the
+ * architecture part of a HostTupleName.
+ *
+ * \ingroup grpnames
+ * \ingroup grpconfigurationname
+ */
+ typedef Validated<std::string, KernelNamePartValidator> KernelNamePart;
+
+ /**
+ * An UserlandNamePartError is thrown if an invalid value is assigned to
+ * an UserlandNamePart.
+ *
+ * \ingroup grpnames
+ * \ingroup grpconfigurationname
+ * \ingroup grpexceptions
+ */
+ class UserlandNamePartError : public HostTupleNameError
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ UserlandNamePartError(const std::string & name) throw ();
+ };
+
+ /**
+ * An UserlandNamePartValidator handles validation rules for the value
+ * of an UserlandNamePart.
+ *
+ * \ingroup grpnames
+ * \ingroup configurationname
+ */
+ struct UserlandNamePartValidator :
+ private InstantiationPolicy<UserlandNamePartValidator, instantiation_method::NonInstantiableTag>
+ {
+ /**
+ * If the parameter is not a valid value for an UserlandNamePart,
+ * throw an UserlandNamePartError.
+ */
+ static void validate(const std::string &);
+ };
+
+ /**
+ * An UserlandNamePart holds a std::string that is a valid name for the
+ * architecture part of a HostTupleName.
+ *
+ * \ingroup grpnames
+ * \ingroup grpconfigurationname
+ */
+ typedef Validated<std::string, UserlandNamePartValidator> UserlandNamePart;
+
+#include <paludis/host_tuple_name-sr.hh>
+
+
+ /**
+ * Output a QualifiedPackageName to a stream.
+ *
+ * \ingroup grpnames
+ * \ingroup grpconfigurationname
+ */
+ std::ostream & operator<< (std::ostream &, const HostTupleName &);
+}
+
+#endif
diff --git a/paludis/host_tuple_name.sr b/paludis/host_tuple_name.sr
new file mode 100644
index 0000000..37dcb8e
--- /dev/null
+++ b/paludis/host_tuple_name.sr
@@ -0,0 +1,27 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+make_class_HostTupleName()
+{
+ key architecture ArchitectureNamePart
+ key manufacturer ManufacturerNamePart
+ key kernel KernelNamePart
+ key userland UserlandNamePart
+
+ comparison_operators all all
+
+ extra_constructors <<END
+ HostTupleName(const std::string &);
+END
+
+ doxygen_comment << "END"
+ /**
+ * Represents a configuration name as expected by autotools.
+ *
+ * \ingroup grpnames
+ * \ingroup grpconfigurationname
+ * \nosubgrouping
+ */
+END
+}
+
diff --git a/paludis/host_tuple_name_TEST.cc b/paludis/host_tuple_name_TEST.cc
new file mode 100644
index 0000000..ff5e0d0
--- /dev/null
+++ b/paludis/host_tuple_name_TEST.cc
@@ -0,0 +1,225 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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/host_tuple_name.hh>
+#include <paludis/util/exception.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+using namespace test;
+using namespace paludis;
+
+/** \file
+ * Test cases for HostTupleName.
+ *
+ */
+
+namespace test_cases
+{
+ /**
+ * \test Basic HostTupleName tests.
+ *
+ */
+ struct HostTupleNameTest : TestCase
+ {
+ HostTupleNameTest() : TestCase("basic") { }
+
+ void run()
+ {
+ HostTupleName a("i686-unknown-linux-gnu");
+ TEST_CHECK(true);
+ }
+ } test_configuration_name;
+
+ /**
+ * \test Validate HostTupleName tests.
+ *
+ */
+ struct HostTupleNameValidateTest : TestCase
+ {
+ HostTupleNameValidateTest() : TestCase("validate") { }
+
+ void run()
+ {
+ HostTupleName a("i686-unknown-linux-gnu");
+ TEST_CHECK_THROWS(a = HostTupleName("moo!"), HostTupleNameError);
+ TEST_CHECK_THROWS(a = HostTupleName("foo-bar!"), HostTupleNameError);
+ TEST_CHECK_THROWS(a = HostTupleName("foo-bar-baz-too-many"), HostTupleNameError);
+ }
+ } test_configuration_name_validate;
+
+ /**
+ * \test Compare HostTupleName tests.
+ *
+ */
+ struct HostTupleNameCompareTest : TestCase
+ {
+ HostTupleNameCompareTest() : TestCase("compare") { }
+
+ void run()
+ {
+ HostTupleName foo1("i386-pc-linux-gnu");
+ HostTupleName foo2("i686-unknown-freebsd6.0");
+ HostTupleName foo3("spu-elf");
+ HostTupleName foo4("i386-pc-linux-gnu");
+
+ TEST_CHECK( (foo1 < foo2));
+ TEST_CHECK( (foo2 < foo3));
+ TEST_CHECK( (foo1 < foo3));
+
+ TEST_CHECK( (foo1 == foo4));
+ }
+ } test_configuration_name_compare;
+
+ /**
+ * \test Test ArchitectureNamePart creation.
+ *
+ */
+ struct ArchitectureNamePartCreationTest : public TestCase
+ {
+ ArchitectureNamePartCreationTest() : TestCase("architecture creation") { }
+
+ void run()
+ {
+ ArchitectureNamePart a("hppa1.1");
+ TEST_CHECK(true);
+ }
+ } architecture_name_part_creation;
+
+ /**
+ * \test Test ArchitectureNamePart validation
+ *
+ */
+ struct ArchitectureNamePartValidationTest : public TestCase
+ {
+ ArchitectureNamePartValidationTest() : TestCase("architecture validation") {}
+
+ void run()
+ {
+ ArchitectureNamePart a = ArchitectureNamePart("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.");
+
+ TEST_CHECK_THROWS(a = ArchitectureNamePart(""), ArchitectureNamePartError);
+ TEST_CHECK_THROWS(a = ArchitectureNamePart("*"), ArchitectureNamePartError);
+ TEST_CHECK_THROWS(a = ArchitectureNamePart("foo bar"), ArchitectureNamePartError);
+ }
+ } architecture_name_part_validation;
+
+ /**
+ * \test Test ManufacturerNamePart creation.
+ *
+ */
+ struct ManufacturerNamePartCreationTest : public TestCase
+ {
+ ManufacturerNamePartCreationTest() : TestCase("manufacturer creation") { }
+
+ void run()
+ {
+ ManufacturerNamePart m1("unknown");
+ ManufacturerNamePart m2("");
+ TEST_CHECK(true);
+ }
+ } manufacturer_name_part_creation;
+
+ /**
+ * \test Test ManufacturerNamePart validation
+ *
+ */
+ struct ManufacturerNamePartValidationTest : public TestCase
+ {
+ ManufacturerNamePartValidationTest() : TestCase("manufacturer validation") {}
+
+ void run()
+ {
+ ManufacturerNamePart m = ManufacturerNamePart("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
+
+ TEST_CHECK_THROWS(m = ManufacturerNamePart("."), ManufacturerNamePartError);
+ TEST_CHECK_THROWS(m = ManufacturerNamePart("*"), ManufacturerNamePartError);
+ TEST_CHECK_THROWS(m = ManufacturerNamePart("foo bar"), ManufacturerNamePartError);
+ }
+ } manufacturer_name_part_validation;
+
+ /**
+ * \test Test KernelNamePart creation.
+ *
+ */
+ struct KernelNamePartCreationTest : public TestCase
+ {
+ KernelNamePartCreationTest() : TestCase("kernel creation") { }
+
+ void run()
+ {
+ KernelNamePart k1("freebsd6.0");
+ KernelNamePart k2("");
+ TEST_CHECK(true);
+ }
+ } kernel_name_part_creation;
+
+ /**
+ * \test Test KernelNamePart validation
+ *
+ */
+ struct KernelNamePartValidationTest : public TestCase
+ {
+ KernelNamePartValidationTest() : TestCase("kernel validation") {}
+
+ void run()
+ {
+ KernelNamePart k = KernelNamePart("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.");
+
+ TEST_CHECK_THROWS(k = KernelNamePart("aixsucks!"), KernelNamePartError);
+ TEST_CHECK_THROWS(k = KernelNamePart("*"), KernelNamePartError);
+ TEST_CHECK_THROWS(k = KernelNamePart("foo bar"), KernelNamePartError);
+ }
+ } kernel_name_part_validation;
+
+ /**
+ * \test Test UserlandNamePart creation.
+ *
+ */
+ struct UserlandNamePartCreationTest : public TestCase
+ {
+ UserlandNamePartCreationTest() : TestCase("userland creation") { }
+
+ void run()
+ {
+ UserlandNamePart u("freebsd6.0");
+ TEST_CHECK(true);
+ }
+ } userland_name_part_creation;
+
+ /**
+ * \test Test UserlandNamePart validation
+ *
+ */
+ struct UserlandNamePartValidationTest : public TestCase
+ {
+ UserlandNamePartValidationTest() : TestCase("userland validation") {}
+
+ void run()
+ {
+ UserlandNamePart u = UserlandNamePart("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.");
+
+ TEST_CHECK_THROWS(u = UserlandNamePart(""), UserlandNamePartError);
+ TEST_CHECK_THROWS(u = UserlandNamePart("*"), UserlandNamePartError);
+ TEST_CHECK_THROWS(u = UserlandNamePart("foo bar"), UserlandNamePartError);
+ }
+ } userland_name_part_validation;
+
+}
+
diff --git a/paludis/tasks/Makefile.am b/paludis/tasks/Makefile.am
index b03694a..5069227 100644
--- a/paludis/tasks/Makefile.am
+++ b/paludis/tasks/Makefile.am
@@ -1,4 +1,5 @@
CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda
+DISTCLEANFILES = stage_options-sr.hh stage_options-sr.cc
MAINTAINERCLEANFILES = Makefile.in
AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
DEFS= \
@@ -24,15 +25,31 @@ paludis_tasks_include_HEADERS = \
install_task.hh \
uninstall_task.hh \
sync_task.hh \
+ stage_builder_task.hh \
+ stage_options-sr.hh \
report_task.hh
libpaludistasks_a_SOURCES = $(paludis_tasks_include_HEADERS) \
install_task.cc \
uninstall_task.cc \
sync_task.cc \
+ stage_builder_task.cc \
report_task.cc
+BUILT_SOURCES = \
+ stage_options-sr.hh \
+ stage_options-sr.cc
+
+EXTRA_DIST = \
+ stage_options.sr \
+ stage_options-sr.hh \
+ stage_options-sr.cc
+
built-sources : $(BUILT_SOURCES)
for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
+stage_options-sr.hh : stage_options.sr $(top_srcdir)/misc/make_sr.bash
+ $(top_srcdir)/misc/make_sr.bash --header $(srcdir)/stage_options.sr > $@
+stage_options-sr.cc : stage_options.sr $(top_srcdir)/misc/make_sr.bash
+ $(top_srcdir)/misc/make_sr.bash --source $(srcdir)/stage_options.sr > $@
diff --git a/paludis/tasks/stage_builder_task.cc b/paludis/tasks/stage_builder_task.cc
new file mode 100644
index 0000000..5b21af5
--- /dev/null
+++ b/paludis/tasks/stage_builder_task.cc
@@ -0,0 +1,119 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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 "stage_builder_task.hh"
+
+#include <paludis/environment.hh>
+#include <list>
+
+using namespace paludis;
+
+namespace paludis
+{
+ template<>
+ struct Implementation<StageBuilderTask> :
+ InternalCounted<Implementation<StageBuilderTask> >
+ {
+ std::list<StageBase::ConstPointer> stages;
+
+ const StageOptions options;
+
+ Implementation(const StageOptions & o) :
+ options(o)
+ {
+ }
+ };
+}
+
+#include <paludis/tasks/stage_options-sr.cc>
+
+StageBase::~StageBase()
+{
+}
+
+StageBuilderTask::StageBuilderTask(const StageOptions & o) :
+ PrivateImplementationPattern<StageBuilderTask>(new Implementation<StageBuilderTask>(o))
+{
+}
+
+StageBuilderTask::~StageBuilderTask()
+{
+}
+
+void
+StageBuilderTask::queue_stage(StageBase::ConstPointer p)
+{
+ Context context("When queuing stage in build list:");
+ _imp->stages.push_back(p);
+}
+
+StageBuilderTask::StageIterator
+StageBuilderTask::begin_stages() const
+{
+ return StageIterator(_imp->stages.begin());
+}
+
+StageBuilderTask::StageIterator
+StageBuilderTask::end_stages() const
+{
+ return StageIterator(_imp->stages.end());
+}
+
+void
+StageBuilderTask::execute()
+{
+ Context context("When executing stage builder task:");
+
+#if 0
+ if (_imp->stages.empty())
+ throw NoStageListError(); //TODO: Needed?
+#endif
+
+ on_build_all_pre();
+
+ for (std::list<StageBase::ConstPointer>::const_iterator
+ s(_imp->stages.begin()), s_end(_imp->stages.end()) ;
+ s != s_end ; ++s)
+ {
+ Context context_local("When building stage '" + (*s)->short_name() + "':");
+
+ on_build_pre(*s);
+
+ try
+ {
+ if (((*s)->is_rebuild()) && (! _imp->options.always_rebuild))
+ {
+ on_build_skipped(*s);
+ continue;
+ }
+ (*s)->build(_imp->options);
+ on_build_succeed(*s);
+ }
+ catch (const StageBuildError & e)
+ {
+ on_build_fail(*s, e);
+ }
+
+
+ on_build_post(*s);
+ }
+
+ on_build_all_post();
+}
+
diff --git a/paludis/tasks/stage_builder_task.hh b/paludis/tasks/stage_builder_task.hh
new file mode 100644
index 0000000..b7c98f5
--- /dev/null
+++ b/paludis/tasks/stage_builder_task.hh
@@ -0,0 +1,142 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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_TASKS_STAGE_BUILDER_TASK_HH
+#define PALUDIS_GUARD_PALUDIS_TASKS_STAGE_BUILDER_TASK_HH 1
+
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
+
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/exception.hh>
+
+namespace paludis
+{
+ /**
+ * Thrown if a stage build fails.
+ *
+ * \ingroup grpstagebuildertask
+ * \nosubgrouping
+ */
+ class StageBuildError :
+ public Exception
+ {
+ protected:
+ /**
+ * Constructor
+ *
+ * \param message Message associated with the build error.
+ */
+ StageBuildError(const std::string & message) throw ();
+ };
+
+ #include <paludis/tasks/stage_options-sr.hh>
+
+ /**
+ * Represents the base class for all stages which can be build by
+ * StageBuilderTask.
+ *
+ * \ingroup grptask
+ * \ingroup grpstagebuildertask
+ * \nosubgrouping
+ */
+ class StageBase :
+ public InternalCounted<StageBase>
+ {
+ public:
+ virtual ~StageBase();
+
+ /// Build the stage.
+ virtual int build(const StageOptions &) const = 0;
+
+ /// Verbose description for this stage.
+ virtual std::string description() const = 0;
+
+ /// Has this stage ever been built before?
+ virtual bool is_rebuild() const = 0;
+
+ /// Short name for this stage.
+ virtual std::string short_name() const = 0;
+ };
+
+ /**
+ * Task to handle building for of one or more descendants of StageBase.
+ *
+ * \ingroup grptasks
+ * \ingroup grpstagehandlertask
+ * \nosubgrouping
+ */
+ class PALUDIS_VISIBLE StageBuilderTask :
+ PrivateImplementationPattern<StageBuilderTask>,
+ InstantiationPolicy<StageBuilderTask, instantiation_method::NonCopyableTag>
+ {
+ protected:
+ ///\name Basic operations
+ ///\{
+
+ StageBuilderTask(const StageOptions &);
+
+ ///\}
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ virtual ~StageBuilderTask();
+
+ ///\}
+
+ ///\name Queue stage in build list
+ ///\{
+
+ void queue_stage(StageBase::ConstPointer);
+
+ ///\}
+
+ ///\name Iterate over our stages
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<StageBuilderTask, const StageBase::ConstPointer> StageIterator;
+ StageIterator begin_stages() const;
+ StageIterator end_stages() const;
+
+ ///\}
+
+ ///\name Event callbacks
+ ///\{
+
+ virtual void on_build_all_pre() = 0;
+ virtual void on_build_pre(StageBase::ConstPointer) = 0;
+ virtual void on_build_post(StageBase::ConstPointer) = 0;
+ virtual void on_build_fail(StageBase::ConstPointer, const StageBuildError &) = 0;
+ virtual void on_build_skipped(StageBase::ConstPointer) = 0;
+ virtual void on_build_succeed(StageBase::ConstPointer) = 0;
+ virtual void on_build_all_post() = 0;
+
+ ///\}
+
+ /**
+ * Run the task
+ */
+
+ void execute();
+ };
+}
+
+#endif
diff --git a/paludis/tasks/stage_options.sr b/paludis/tasks/stage_options.sr
new file mode 100644
index 0000000..9fce610
--- /dev/null
+++ b/paludis/tasks/stage_options.sr
@@ -0,0 +1,19 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+make_class_StageOptions()
+{
+ key pretend bool
+ key fetch_only bool
+ key always_rebuild bool
+
+ doxygen_comment << "END"
+ /**
+ * Represents the options passed to a descendant of StageBase on execution.
+ *
+ * \see StageBase
+ * \ingroup grpstagehandlertask
+ * \nosubgrouping
+ */
+END
+}
diff --git a/src/Makefile.am b/src/Makefile.am
index b694109..0bdbad1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = . paludis gtkpaludis qualudis adjutrix
+SUBDIRS = . paludis gtkpaludis qualudis adjutrix contrarius
CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda
MAINTAINERCLEANFILES = Makefile.in
diff --git a/src/colour.hh b/src/colour.hh
index 1e42b0b..b49b33f 100644
--- a/src/colour.hh
+++ b/src/colour.hh
@@ -74,7 +74,11 @@ enum Colour
cl_file = cl_none,
cl_dir = cl_blue,
cl_sym = cl_pink,
- cl_misc = cl_red
+ cl_misc = cl_red,
+
+ /* Contrarius colours */
+ cl_stage_short_name = cl_blue,
+ cl_stage_long_name = cl_yellow
};
bool use_colour();
diff --git a/src/contrarius/Makefile.am b/src/contrarius/Makefile.am
new file mode 100644
index 0000000..e1fd9f2
--- /dev/null
+++ b/src/contrarius/Makefile.am
@@ -0,0 +1,80 @@
+AM_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src @PALUDIS_CXXFLAGS@
+DEFS= \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DBIGTEMPDIR=\"/var/tmp\" \
+ -DLIBDIR=\"$(libdir)\"
+SUBDIRS = .
+
+man_pages = contrarius.1
+
+bin_PROGRAMS = contrarius
+noinst_PROGRAMS = man-contrarius
+man_MANS = $(man_pages)
+
+contrarius_SOURCES = \
+ command_line.hh \
+ command_line.cc \
+ contrarius.cc \
+ install.hh \
+ install.cc \
+ stage.hh \
+ stage.cc \
+ stage_builder.hh \
+ stage_builder.cc
+
+contrarius_LDADD = \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/environment/default/libpaludisdefaultenvironment.la \
+ $(top_builddir)/paludis/tasks/libpaludistasks.a \
+ $(top_builddir)/paludis/args/libpaludisargs.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(top_builddir)/paludis/dep_list/libpaludisdeplist.la \
+ $(top_builddir)/src/liboutput.a \
+ $(DYNAMIC_LD_LIBS)
+
+contrarius_stage_options-sr.hh : contrarius_stage_options.sr $(top_srcdir)/misc/make_sr.bash
+ $(top_srcdir)/misc/make_sr.bash --header $(srcdir)/contrarius_stage_options.sr > $@
+
+contrarius_stage_options-sr.cc : contrarius_stage_options.sr $(top_srcdir)/misc/make_sr.bash
+ $(top_srcdir)/misc/make_sr.bash --source $(srcdir)/contrarius_stage_options.sr > $@
+
+BUILT_SOURCES = \
+ contrarius_stage_options-sr.hh \
+ contrarius_stage_options-sr.cc
+
+TESTS_ENVIRONMENT = env \
+ TEST_SCRIPT_DIR="$(srcdir)/" \
+ PALUDIS_REPOSITORY_SO_DIR="$(top_builddir)/paludis/repositories" \
+ bash $(top_srcdir)/test/run_test.sh bash
+
+TESTS = version_TEST
+
+version_TEST :
+ echo -e "#!/bin/sh\n./contrarius --version" > $@
+
+contrarius.1 : man-contrarius
+ ./man-contrarius | tee $@ | sed -e 's/^/ /'
+
+man_contrarius_SOURCES = \
+ man_contrarius.cc \
+ command_line.hh \
+ command_line.cc
+
+man_contrarius_LDADD = \
+ $(top_builddir)/paludis/args/libpaludisargs.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(top_builddir)/src/liboutput.a \
+ $(DYNAMIC_LD_LIBS)
+
+CLEANFILES = *~ version_TEST gmon.out *.gcov *.gcno *.gcda
+DISTCLEANFILES = $(man_pages) contrarius_stage_options-sr.hh contrarius_stage_options-sr.cc
+MAINTAINERCLEANFILES = Makefile.in
+EXTRA_DIST = \
+ $(man_pages) \
+ contrarius_stage_options.sr \
+ contrarius_stage_options-sr.hh \
+ contrarius_stage_options-sr.cc
+
+built-sources : $(BUILT_SOURCES)
+ for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
diff --git a/src/contrarius/command_line.cc b/src/contrarius/command_line.cc
new file mode 100644
index 0000000..0e2f457
--- /dev/null
+++ b/src/contrarius/command_line.cc
@@ -0,0 +1,105 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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 "command_line.hh"
+
+CommandLine::CommandLine() :
+ ArgsHandler(),
+
+ action_args(this, "Actions",
+ "Selects which basic action to perform. Up to one action should "
+ "be specified. If no action is specified, contrarius tries to create"
+ "a cross toolchain."),
+ a_version(&action_args, "version", 'V', "Display program version"),
+ a_help(&action_args, "help", 'h', "Display program help"),
+
+ build_args(this, "Building",
+ "Tweak toolchain creation."),
+ a_fetch(&build_args, "fetch", 'f', "Only fetch sources; don't install anything"),
+ a_show_install_reasons(&build_args, "show-install-reasons", '\0', "Show why packages are being installed",
+ paludis::args::EnumArg::EnumArgOptions
+ ("none", "Don't show any information")
+ ("summary", "Show a summary")
+ ("full", "Show full output (can be very verbose)"),
+ "none"),
+ a_pretend(&build_args, "pretend", 'p', "Pretend only"),
+ a_stage(&build_args, "stage", 's', "Build specified toolchain stage.",
+ paludis::args::EnumArg::EnumArgOptions("binutils","Build binutils only")
+ ("minimal", "Build a minimal gcc additionaly")
+ ("headers", "Build kernel headers additionaly")
+ ("libc", "Build the C Standard Library additionally")
+ ("full", "Build a full cross toolchain."),
+ "binutils"),
+ a_target(&build_args, "target", 't', "Build for specified CTARGET."),
+ a_always_rebuild(&build_args, "always-rebuild", 'r', "Always rebuild already built stages."),
+ a_headers(&build_args, "headers", 'H', "Add additional stage to install kernel- and libc-headers before gcc."),
+ a_debug_build(&build_args, "debug-build", '\0', "What to do with debug information",
+ paludis::args::EnumArg::EnumArgOptions
+ ("none", "Discard debug information")
+ ("split", "Split debug information")
+ ("internal", "Keep debug information with binaries"),
+ "none"),
+
+ package_options(this, "Options to adjust package names and versions", ""),
+ a_binutils_name(&package_options, "binutils-name", '\0', "Package name for the binutils stage."),
+ a_binutils_version(&package_options, "binutils-version", '\0', "Package version for the binutils stage."),
+ a_gcc_name(&package_options, "gcc-name", '\0', "Package name for the minima/full stage."),
+ a_gcc_version(&package_options, "gcc-version", '\0', "Package version for the system headers stage."),
+ a_headers_name(&package_options, "headers-name", '\0', "Package name for the system headers stage."),
+ a_headers_version(&package_options, "headers-version", '\0', "Package version for the minima/full stage."),
+ a_libc_name(&package_options, "libc-name", '\0', "Package name for the libc stage."),
+ a_libc_version(&package_options, "libc-version", '\0', "Package version for the libc stage."),
+
+ output_options(this, "Options for output verbosity",
+ ""),
+ a_verbose(&output_options, "verbose", 'v', "Be verbose"),
+ a_log_level(&output_options, "log-level", 'L', "Specify the log level",
+ paludis::args::EnumArg::EnumArgOptions("debug", "Show debug output (noisy)")
+ ("qa", "Show QA messages and warnings only")
+ ("warning", "Show warnings only")
+ ("silent", "Suppress all log messages"),
+ "warning"),
+ a_no_colour(&output_options, "no-colour", 'C', "Do not use colour"),
+ a_no_color(&a_no_colour, "no-color"),
+ a_resume_command_template(&output_options, "resume-command-template", '\0', "Save the resume command to a file made using mkstemp(3)")
+{
+}
+
+CommandLine::~CommandLine()
+{
+}
+
+std::string
+CommandLine::app_name() const
+{
+ return "contrarius";
+}
+
+std::string
+CommandLine::app_synopsis() const
+{
+ return "A tool to create cross-toolchains";
+}
+
+std::string
+CommandLine::app_description() const
+{
+ return
+ "contrarius.";
+}
diff --git a/src/contrarius/command_line.hh b/src/contrarius/command_line.hh
new file mode 100644
index 0000000..682c379
--- /dev/null
+++ b/src/contrarius/command_line.hh
@@ -0,0 +1,147 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+#ifndef PALUDIS_GUARD_SRC_CONTRARIUS_COMMAND_LINE_HH
+#define PALUDIS_GUARD_SRC_CONTRARIUS_COMMAND_LINE_HH 1
+
+#include <paludis/args/args.hh>
+#include <paludis/qa/message.hh>
+#include <paludis/util/instantiation_policy.hh>
+
+class CommandLine :
+ public paludis::args::ArgsHandler,
+ public paludis::InstantiationPolicy<CommandLine, paludis::instantiation_method::SingletonAsNeededTag>
+{
+ friend class paludis::InstantiationPolicy<CommandLine, paludis::instantiation_method::SingletonAsNeededTag>;
+
+ private:
+ /// Constructor.
+ CommandLine();
+
+ /// Destructor.
+ ~CommandLine();
+
+ public:
+ ///\name Program information
+ ///\{
+
+ virtual std::string app_name() const;
+ virtual std::string app_synopsis() const;
+ virtual std::string app_description() const;
+
+ ///\}
+
+ ///\name Action arguments
+ ///\{
+
+ /// Action arguments.
+ paludis::args::ArgsGroup action_args;
+
+ /// --version
+ paludis::args::SwitchArg a_version;
+
+ /// --help
+ paludis::args::SwitchArg a_help;
+
+ ///\}
+
+ ///\name Build arguments
+ ///\{
+
+ /// Build arguments.
+ paludis::args::ArgsGroup build_args;
+
+ /// --fetch
+ paludis::args::SwitchArg a_fetch;
+
+ /// --pretend
+ paludis::args::SwitchArg a_pretend;
+
+ /// --show-install-reasons
+ paludis::args::EnumArg a_show_install_reasons;
+
+ /// --stage
+ paludis::args::EnumArg a_stage;
+
+ /// --target
+ paludis::args::StringArg a_target;
+
+ /// --headers \todo Find a better name!
+ paludis::args::SwitchArg a_headers;
+
+ /// --always-rebuild
+ paludis::args::SwitchArg a_always_rebuild;
+
+ /// --debug-build
+ paludis::args::EnumArg a_debug_build;
+
+ ///\}
+
+ ///\name Package options
+ ///\[
+
+ /// Package options.
+ paludis::args::ArgsGroup package_options;
+
+ /// Bintuils name
+ paludis::args::StringArg a_binutils_name;
+
+ /// Binutils version
+ paludis::args::StringArg a_binutils_version;
+
+ /// Gcc name
+ paludis::args::StringArg a_gcc_name;
+
+ /// Gcc version
+ paludis::args::StringArg a_gcc_version;
+
+ /// Headers name
+ paludis::args::StringArg a_headers_name;
+
+ /// Headers version
+ paludis::args::StringArg a_headers_version;
+
+ /// Libc name
+ paludis::args::StringArg a_libc_name;
+
+ /// Libc version
+ paludis::args::StringArg a_libc_version;
+
+ ///\}
+
+ ///\name Output options
+ ///\{
+
+ /// Output options.
+ paludis::args::ArgsGroup output_options;
+
+ /// --verbose
+ paludis::args::SwitchArg a_verbose;
+
+ /// --log-level
+ paludis::args::EnumArg a_log_level;
+
+ /// --no-colour
+ paludis::args::SwitchArg a_no_colour;
+
+ /// --no-color
+ paludis::args::AliasArg a_no_color;
+
+ /// --resume-command-template
+ paludis::args::StringArg a_resume_command_template;
+ ///\}
+};
+
+/**
+ * Show the help message.
+ */
+struct DoHelp
+{
+ const std::string message;
+
+ DoHelp(const std::string & m = "") :
+ message(m)
+ {
+ }
+};
+
+#endif
diff --git a/src/contrarius/contrarius.cc b/src/contrarius/contrarius.cc
new file mode 100644
index 0000000..ced1f3b
--- /dev/null
+++ b/src/contrarius/contrarius.cc
@@ -0,0 +1,211 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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/args/args.hh>
+#include <paludis/paludis.hh>
+#include <paludis/util/util.hh>
+
+#include <cstdlib>
+#include <iostream>
+#include <algorithm>
+
+#include <libebt/libebt.hh>
+#include <libwrapiter/libwrapiter.hh>
+
+#include "command_line.hh"
+#include "stage.hh"
+#include "config.h"
+#include "stage_builder.hh"
+
+using namespace paludis;
+using std::cout;
+using std::cerr;
+using std::endl;
+
+struct DoVersion
+{
+};
+
+int main(int argc, char *argv[])
+{
+ Context context("In main program:");
+
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv);
+
+ if (CommandLine::get_instance()->a_help.specified())
+ throw DoHelp();
+
+ if (! CommandLine::get_instance()->a_log_level.specified())
+ Log::get_instance()->set_log_level(ll_qa);
+ else if (CommandLine::get_instance()->a_log_level.argument() == "debug")
+ Log::get_instance()->set_log_level(ll_debug);
+ else if (CommandLine::get_instance()->a_log_level.argument() == "qa")
+ Log::get_instance()->set_log_level(ll_qa);
+ else if (CommandLine::get_instance()->a_log_level.argument() == "warning")
+ Log::get_instance()->set_log_level(ll_warning);
+ else if (CommandLine::get_instance()->a_log_level.argument() == "silent")
+ Log::get_instance()->set_log_level(ll_silent);
+ else
+ throw DoHelp("bad value for --log-level");
+
+ if (CommandLine::get_instance()->a_version.specified())
+ throw DoVersion();
+
+ if (! CommandLine::get_instance()->a_target.specified())
+ throw DoHelp("you need to specify a --target");
+
+ std::string stage;
+ if (CommandLine::get_instance()->a_stage.specified())
+ stage = CommandLine::get_instance()->a_stage.argument();
+ else
+ stage = "cxx";
+
+ ContrariusStageOptions contrarius_opts(HostTupleName(CommandLine::get_instance()->a_target.argument()),
+ CommandLine::get_instance()->a_binutils_name.argument(),
+ CommandLine::get_instance()->a_binutils_version.argument(),
+ CommandLine::get_instance()->a_gcc_name.argument(),
+ CommandLine::get_instance()->a_gcc_version.argument(),
+ CommandLine::get_instance()->a_headers_name.argument(),
+ CommandLine::get_instance()->a_headers_version.argument(),
+ CommandLine::get_instance()->a_libc_name.argument(),
+ CommandLine::get_instance()->a_libc_version.argument());
+
+ StageOptions stage_opts(CommandLine::get_instance()->a_pretend.specified(),
+ CommandLine::get_instance()->a_fetch.specified(),
+ CommandLine::get_instance()->a_always_rebuild.specified());
+
+ OurStageBuilderTask builder(stage_opts);
+
+ builder.queue_stage(StageBase::ConstPointer(new BinutilsStage(contrarius_opts)));
+
+ if (stage == "binutils")
+ goto run;
+
+ builder.queue_stage(StageBase::ConstPointer(new MinimalStage(contrarius_opts)));
+
+ if (stage == "minimal")
+ goto run;
+
+ builder.queue_stage(StageBase::ConstPointer(new KernelHeadersStage(contrarius_opts)));
+
+ if (stage == "headers")
+ goto run;
+
+ builder.queue_stage(StageBase::ConstPointer(new LibCStage(contrarius_opts)));
+
+ if (stage == "libc")
+ goto run;
+
+ builder.queue_stage(StageBase::ConstPointer(new FullStage(contrarius_opts)));
+
+ run:
+ builder.execute();
+
+ return EXIT_SUCCESS;
+ }
+ catch (const DoVersion &)
+ {
+ cout << "contrarius, part of " << PALUDIS_PACKAGE << " " << PALUDIS_VERSION_MAJOR << "."
+ << PALUDIS_VERSION_MINOR << "." << PALUDIS_VERSION_MICRO;
+ if (! std::string(PALUDIS_SUBVERSION_REVISION).empty())
+ cout << " svn " << PALUDIS_SUBVERSION_REVISION;
+ cout << endl << endl;
+ cout << "Built by " << PALUDIS_BUILD_USER << "@" << PALUDIS_BUILD_HOST
+ << " on " << PALUDIS_BUILD_DATE << endl;
+ cout << "CXX: " << PALUDIS_BUILD_CXX
+#if defined(__ICC)
+ << " " << __ICC
+#elif defined(__VERSION__)
+ << " " << __VERSION__
+#endif
+ << endl;
+ cout << "CXXFLAGS: " << PALUDIS_BUILD_CXXFLAGS << endl;
+ cout << "LDFLAGS: " << PALUDIS_BUILD_LDFLAGS << endl;
+ cout << "SYSCONFDIR: " << SYSCONFDIR << endl;
+ cout << "LIBEXECDIR: " << LIBEXECDIR << endl;
+ cout << "BIGTEMPDIR: " << BIGTEMPDIR << endl;
+ cout << "stdlib: "
+#if defined(__GLIBCXX__)
+# define XSTRINGIFY(x) #x
+# define STRINGIFY(x) XSTRINGIFY(x)
+ << "GNU libstdc++ " << STRINGIFY(__GLIBCXX__)
+#endif
+ << endl;
+
+ cout << "libebt: " << LIBEBT_VERSION_MAJOR << "." << LIBEBT_VERSION_MINOR
+ << "." << LIBEBT_VERSION_MICRO << endl;
+ cout << "libwrapiter: " << LIBWRAPITER_VERSION_MAJOR << "." << LIBWRAPITER_VERSION_MINOR
+ << "." << LIBWRAPITER_VERSION_MICRO << endl;
+
+ cout << endl;
+ cout << "Paludis comes with ABSOLUTELY NO WARRANTY. Paludis is free software, and you" << endl;
+ cout << "are welcome to redistribute it under the terms of the GNU General Public" << endl;
+ cout << "License, version 2." << endl;
+
+ return EXIT_SUCCESS;
+ }
+ catch (const paludis::args::ArgsError & e)
+ {
+ cerr << "Usage error: " << e.message() << endl;
+ cerr << "Try " << argv[0] << " --help" << endl;
+ return EXIT_FAILURE;
+ }
+ catch (const DoHelp & h)
+ {
+ if (h.message.empty())
+ {
+ cout << "Usage: " << argv[0] << " [options]" << endl;
+ cout << " or: " << argv[0] << " [package/category ..]" << endl;
+ cout << endl;
+ cout << *CommandLine::get_instance();
+ return EXIT_SUCCESS;
+ }
+ else
+ {
+ cerr << "Usage error: " << h.message << endl;
+ cerr << "Try " << argv[0] << " --help" << endl;
+ return EXIT_FAILURE;
+ }
+ }
+ catch (const Exception & e)
+ {
+ cout << endl;
+ cerr << "Unhandled exception:" << endl
+ << " * " << e.backtrace("\n * ")
+ << e.message() << " (" << e.what() << ")" << endl;
+ return EXIT_FAILURE;
+ }
+ catch (const std::exception & e)
+ {
+ cout << endl;
+ cerr << "Unhandled exception:" << endl
+ << " * " << e.what() << endl;
+ return EXIT_FAILURE;
+ }
+ catch (...)
+ {
+ cout << endl;
+ cerr << "Unhandled exception:" << endl
+ << " * Unknown exception type. Ouch..." << endl;
+ return EXIT_FAILURE;
+ }
+}
+
diff --git a/src/contrarius/install.cc b/src/contrarius/install.cc
new file mode 100644
index 0000000..4daaeff
--- /dev/null
+++ b/src/contrarius/install.cc
@@ -0,0 +1,373 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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 "colour.hh"
+#include "install.hh"
+#include "licence.hh"
+#include "console_install_task.hh"
+
+#include <iostream>
+#include <limits>
+#include <set>
+
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <paludis/tasks/install_task.hh>
+#include <paludis/util/fd_output_stream.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/tokeniser.hh>
+#include <paludis/environment/default/default_environment.hh>
+
+/** \file
+ * Handle the --install action for the contrarius program.
+ */
+
+using namespace paludis;
+
+using std::cerr;
+using std::cout;
+using std::endl;
+
+namespace
+{
+ class OurInstallTask :
+ public ConsoleInstallTask
+ {
+ public:
+ OurInstallTask(const DepListOptions & options) :
+ ConsoleInstallTask(DefaultEnvironment::get_instance(), options)
+ {
+ }
+
+ virtual bool want_full_install_reasons() const
+ {
+ return "full" == CommandLine::get_instance()->a_show_install_reasons.argument();
+ }
+
+ virtual bool want_tags_summary() const
+ {
+ return CommandLine::get_instance()->a_pretend.specified();
+ }
+
+ virtual bool want_install_reasons() const
+ {
+ return "full" == CommandLine::get_instance()->a_show_install_reasons.argument() ||
+ "summary" == CommandLine::get_instance()->a_show_install_reasons.argument();
+ }
+ };
+
+ void show_resume_command(const InstallTask & task)
+ {
+ if (CommandLine::get_instance()->a_fetch.specified() ||
+ CommandLine::get_instance()->a_pretend.specified())
+ return;
+
+ if (task.current_dep_list_entry() != task.dep_list().end())
+ {
+ std::string resume_command = DefaultEnvironment::get_instance()->paludis_command() + " "
+ "--dl-installed-deps-pre discard "
+ "--dl-installed-deps-runtime discard "
+ "--dl-installed-deps-post discard "
+ "--dl-uninstalled-deps-pre discard "
+ "--dl-uninstalled-deps-runtime discard "
+ "--dl-uninstalled-deps-post discard "
+ "--install --preserve-world";
+ for (DepList::Iterator i(task.current_dep_list_entry()), i_end(task.dep_list().end()) ;
+ i != i_end ; ++i)
+ if (! i->skip_install)
+ resume_command = resume_command + " ="
+ + stringify(i->package.name) + "-"
+ + stringify(i->package.version) + "::"
+ + stringify(i->package.repository);
+
+ if (CommandLine::get_instance()->a_resume_command_template.specified())
+ {
+ std::string file_name(CommandLine::get_instance()->a_resume_command_template.argument());
+ char* resume_template = strdup(file_name.c_str());
+ FDOutputStream resume_command_file(mkstemp(resume_template));
+ cerr << endl;
+ cerr << "Resume command saved to file: " << resume_template;
+ cerr << endl;
+ resume_command_file << resume_command << endl;
+ std::free(resume_template);
+ }
+ else
+ cerr << "Resume command: " << resume_command << endl;
+ }
+ }
+
+ class InstallKilledCatcher
+ {
+ private:
+ static const InstallTask * _task;
+
+ static void _signal_handler(int sig) PALUDIS_ATTRIBUTE((noreturn));
+
+ sig_t _old;
+
+ public:
+ InstallKilledCatcher(const InstallTask & task) :
+ _old(signal(SIGINT, &InstallKilledCatcher::_signal_handler))
+ {
+ _task = &task;
+ }
+
+ ~InstallKilledCatcher()
+ {
+ signal(SIGINT, _old);
+ _task = 0;
+ }
+ };
+
+ const InstallTask * InstallKilledCatcher::_task(0);
+
+ void
+ InstallKilledCatcher::_signal_handler(int sig)
+ {
+ cout << endl;
+ cerr << "Caught signal " << sig << endl;
+ cerr << "Waiting for children..." << endl;
+ while (-1 != wait(0))
+ ;
+ cerr << endl;
+ if (_task)
+ show_resume_command(*_task);
+ cerr << endl;
+ cerr << "Exiting with failure" << endl;
+ exit(EXIT_FAILURE);
+ }
+
+ DepListDepsOption
+ enum_arg_to_dep_list_deps_option(const args::EnumArg & arg)
+ {
+ if (arg.argument() == "pre")
+ return dl_deps_pre;
+ else if (arg.argument() == "pre-or-post")
+ return dl_deps_pre_or_post;
+ else if (arg.argument() == "post")
+ return dl_deps_post;
+ else if (arg.argument() == "try-post")
+ return dl_deps_try_post;
+ else if (arg.argument() == "discard")
+ return dl_deps_discard;
+ else
+ throw DoHelp("bad value for --" + arg.long_name());
+ }
+}
+
+int
+do_install(PackageDepAtom::ConstPointer atom)
+{
+ int return_code(0);
+
+ Context context("When performing install action from command line:");
+
+ DepListOptions options;
+
+ options.circular = dl_circular_discard;
+ options.circular = dl_circular_error;
+ options.installed_deps_pre = dl_deps_discard;
+ options.installed_deps_runtime = dl_deps_discard;
+ options.installed_deps_post = dl_deps_discard;
+ options.uninstalled_deps_pre = dl_deps_discard;
+ options.uninstalled_deps_runtime = dl_deps_discard;
+ options.uninstalled_deps_post = dl_deps_discard;
+ options.reinstall = dl_reinstall_never;
+ options.target_type = dl_target_set;
+
+ OurInstallTask task(options);
+ task.set_fetch_only(CommandLine::get_instance()->a_fetch.specified());
+ task.set_pretend(CommandLine::get_instance()->a_pretend.specified());
+
+ if (CommandLine::get_instance()->a_debug_build.specified())
+ {
+ if (CommandLine::get_instance()->a_debug_build.argument() == "none")
+ task.set_debug_mode(ido_none);
+ else if (CommandLine::get_instance()->a_debug_build.argument() == "split")
+ task.set_debug_mode(ido_split);
+ else if (CommandLine::get_instance()->a_debug_build.argument() == "internal")
+ task.set_debug_mode(ido_internal);
+ else
+ throw DoHelp("bad value for --debug-build");
+ }
+
+ try
+ {
+ task.add_target(stringify(*atom));
+
+ task.execute();
+
+ cout << endl;
+ }
+ catch (const AmbiguousPackageNameError & e)
+ {
+ cout << endl;
+ cerr << "Query error:" << endl;
+ cerr << " * " << e.backtrace("\n * ");
+ cerr << "Ambiguous package name '" << e.name() << "'. Did you mean:" << endl;
+ for (AmbiguousPackageNameError::OptionsIterator o(e.begin_options()),
+ o_end(e.end_options()) ; o != o_end ; ++o)
+ cerr << " * " << colour(cl_package_name, *o) << endl;
+ cerr << endl;
+ return 1;
+ }
+ catch (const PackageInstallActionError & e)
+ {
+ cout << endl;
+ cerr << "Install error:" << endl;
+ cerr << " * " << e.backtrace("\n * ");
+ cerr << e.message() << endl;
+ cerr << endl;
+
+ return_code |= 1;
+ }
+ catch (const PackageFetchActionError & e)
+ {
+ cout << endl;
+ cerr << "Fetch error:" << endl;
+ cerr << " * " << e.backtrace("\n * ");
+ cerr << e.message() << endl;
+ cerr << endl;
+
+ return_code |= 1;
+ }
+ catch (const NoSuchPackageError & e)
+ {
+ cout << endl;
+ cerr << "Query error:" << endl;
+ cerr << " * " << e.backtrace("\n * ");
+ cerr << "No such package '" << e.name() << "'" << endl;
+ return 1;
+ }
+ catch (const AllMaskedError & e)
+ {
+ try
+ {
+ PackageDatabaseEntryCollection::ConstPointer p(
+ DefaultEnvironment::get_instance()->package_database()->query(
+ PackageDepAtom::ConstPointer(new PackageDepAtom(e.query())),
+ is_uninstalled_only));
+ if (p->empty())
+ {
+ cout << endl;
+ cerr << "Query error:" << endl;
+ cerr << " * " << e.backtrace("\n * ");
+ cerr << "All versions of '" << e.query() << "' are masked" << endl;
+ }
+ else
+ {
+ cout << endl;
+ cerr << "Query error:" << endl;
+ cerr << " * " << e.backtrace("\n * ");
+ cerr << "All versions of '" << e.query() << "' are masked. Candidates are:" << endl;
+ for (PackageDatabaseEntryCollection::Iterator pp(p->begin()), pp_end(p->end()) ;
+ pp != pp_end ; ++pp)
+ {
+ cerr << " * " << colour(cl_package_name, *pp) << ": Masked by ";
+
+ bool need_comma(false);
+ MaskReasons m(DefaultEnvironment::get_instance()->mask_reasons(*pp));
+ for (unsigned mm = 0 ; mm < m.size() ; ++mm)
+ if (m[mm])
+ {
+ if (need_comma)
+ cerr << ", ";
+ cerr << MaskReason(mm);
+
+ if (mr_eapi == mm)
+ {
+ std::string eapi_str(DefaultEnvironment::get_instance()->
+ package_database()->fetch_repository(
+ pp->repository)->version_metadata(
+ pp->name, pp->version)->eapi);
+
+ cerr << " ( " << colour(cl_masked, eapi_str) << " )";
+ }
+ else if (mr_license == mm)
+ {
+ cerr << " ";
+
+ LicenceDisplayer ld(cerr, DefaultEnvironment::get_instance(), &*pp);
+ DefaultEnvironment::get_instance()->package_database()->fetch_repository(
+ pp->repository)->version_metadata(
+ pp->name, pp->version)->license()->
+ accept(&ld);
+ }
+ else if (mr_keyword == mm)
+ {
+ VersionMetadata::ConstPointer meta(DefaultEnvironment::get_instance()->
+ package_database()->fetch_repository(
+ pp->repository)->version_metadata(
+ pp->name, pp->version));
+ if (meta->get_ebuild_interface())
+ {
+ std::set<KeywordName> keywords;
+ WhitespaceTokeniser::get_instance()->tokenise(
+ meta->get_ebuild_interface()->keywords,
+ create_inserter<KeywordName>(
+ std::inserter(keywords, keywords.end())));
+
+ cerr << " ( " << colour(cl_masked, join(keywords.begin(),
+ keywords.end(), " ")) << " )";
+ }
+ }
+
+ need_comma = true;
+ }
+ cerr << endl;
+ }
+ }
+ }
+ catch (...)
+ {
+ throw e;
+ }
+
+ return 1;
+ }
+ catch (const UseRequirementsNotMetError & e)
+ {
+ cout << endl;
+ cerr << "DepList USE requirements not met error:" << endl;
+ cerr << " * " << e.backtrace("\n * ") << e.message() << endl;
+ cerr << endl;
+ cerr << "This error usually indicates that one of the packages you are trying to" << endl;
+ cerr << "install requires that another package be built with particular USE flags" << endl;
+ cerr << "enabled or disabled. You may be able to work around this restriction by" << endl;
+ cerr << "adjusting your use.conf." << endl;
+ cerr << endl;
+
+ return_code |= 1;
+ }
+ catch (const DepListError & e)
+ {
+ cout << endl;
+ cerr << "Dependency error:" << endl;
+ cerr << " * " << e.backtrace("\n * ") << e.message() << " ("
+ << e.what() << ")" << endl;
+ cerr << endl;
+
+ return_code |= 1;
+ }
+
+ return return_code;
+}
+
diff --git a/src/contrarius/install.hh b/src/contrarius/install.hh
new file mode 100644
index 0000000..30ba877
--- /dev/null
+++ b/src/contrarius/install.hh
@@ -0,0 +1,34 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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_SRC_DEPGRAPH_HH
+#define PALUDIS_GUARD_SRC_DEPGRAPH_HH 1
+
+#include <paludis/dep_atom.hh>
+
+#include "command_line.hh"
+
+/** \file
+ * Declaration for the do_install function.
+ */
+
+/// Handle --install.
+int do_install(paludis::PackageDepAtom::ConstPointer atom);
+
+#endif
diff --git a/src/contrarius/man_contrarius.cc b/src/contrarius/man_contrarius.cc
new file mode 100644
index 0000000..89c480e
--- /dev/null
+++ b/src/contrarius/man_contrarius.cc
@@ -0,0 +1,37 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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 "command_line.hh"
+#include <paludis/args/man.hh>
+#include "config.h"
+
+#include <iostream>
+#include <cstdlib>
+
+using std::cout;
+using std::endl;
+
+int
+main(int, char *[])
+{
+ paludis::args::generate_man(cout, CommandLine::get_instance());
+ return EXIT_SUCCESS;
+}
+
+
diff --git a/src/contrarius/stage.cc b/src/contrarius/stage.cc
new file mode 100644
index 0000000..37de13c
--- /dev/null
+++ b/src/contrarius/stage.cc
@@ -0,0 +1,183 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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_environment.hh>
+#include <paludis/environment/default/default_config.hh>
+#include <paludis/util/log.hh>
+#include <string>
+
+#include "stage.hh"
+#include "install.hh"
+
+using namespace paludis;
+
+namespace
+{
+ const PackageDepAtom * make_atom(const HostTupleName & target,
+ const std::string & name,
+ const std::string & default_name,
+ const std::string & version)
+ {
+ return new PackageDepAtom("cross-" + stringify(target) + "/"
+ + (name.empty() ? default_name : name) + (version.empty() ? "" : "-" + version));
+ }
+}
+
+#include <src/contrarius/contrarius_stage_options-sr.cc>
+
+ContrariusStageOptions::ContrariusStageOptions(const HostTupleName & _target,
+ const std::string & binutils_name,
+ const std::string & binutils_version,
+ const std::string & gcc_name,
+ const std::string & gcc_version,
+ const std::string & headers_name,
+ const std::string & headers_version,
+ const std::string & libc_name,
+ const std::string & libc_version) :
+ target(_target),
+ binutils(::make_atom(target, binutils_name, "binutils", binutils_version)),
+ gcc(::make_atom(target, gcc_name, "gcc", gcc_version)),
+ headers(::make_atom(target, headers_name, "linux-headers", headers_version)),
+ libc(::make_atom(target, libc_name, "glibc", libc_version))
+{
+}
+
+int
+BinutilsStage::build(const StageOptions &) const
+{
+ Context context("When building BinutilsStage:");
+
+ DefaultConfig::get_instance()->clear_forced_use_config();
+
+ return do_install(_options.binutils);
+}
+
+bool
+BinutilsStage::is_rebuild() const
+{
+ return (! DefaultEnvironment::get_instance()->package_database()->query(_options.binutils, is_installed_only)->empty());
+}
+
+int
+KernelHeadersStage::build(const StageOptions &) const
+{
+ Context context("When building KernelHeadersStage:");
+
+ DefaultConfig::get_instance()->clear_forced_use_config();
+
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.headers, UseFlagName("crosscompile_opts_headers-only"),
+ use_disabled));
+
+ return do_install(_options.headers);
+}
+
+bool
+KernelHeadersStage::is_rebuild() const
+{
+ return (! DefaultEnvironment::get_instance()->package_database()->query(_options.headers, is_installed_only)->empty());
+}
+
+int
+MinimalStage::build(const StageOptions &) const
+{
+ Context context("When executing MinimalStage:");
+
+ DefaultConfig::get_instance()->clear_forced_use_config();
+
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("boundschecking"), use_disabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("fortran"), use_disabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("gtk"), use_disabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("gcj"), use_disabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("mudflap"), use_disabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("objc"), use_disabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("objc-gc"), use_disabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("nocxx"), use_enabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("crosscompile_opts_bootstrap"), use_enabled));
+
+ return do_install(_options.gcc);
+}
+
+bool
+MinimalStage::is_rebuild() const
+{
+ return (! DefaultEnvironment::get_instance()->package_database()
+ ->query(_options.gcc, is_installed_only)->empty());
+}
+
+int
+LibCStage::build(const StageOptions &) const
+{
+ Context context("When building LibCStage:");
+
+ DefaultConfig::get_instance()->clear_forced_use_config();
+
+ return do_install(_options.libc);
+}
+
+bool
+LibCStage::is_rebuild() const
+{
+ return (! DefaultEnvironment::get_instance()->package_database()
+ ->query(_options.libc, is_installed_only)->empty());
+}
+
+int
+FullStage::build(const StageOptions &) const
+{
+ Context context("When building FullStage:");
+
+ DefaultConfig::get_instance()->clear_forced_use_config();
+
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("boundschecking"), use_disabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("gtk"), use_disabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("gcj"), use_disabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("mudflap"), use_disabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("objc"), use_disabled));
+ DefaultConfig::get_instance()->add_forced_use_config(UseConfigEntry(
+ _options.gcc, UseFlagName("objc-gc"), use_disabled));
+
+ return do_install(_options.gcc);
+}
+
+bool
+FullStage::is_rebuild() const
+{
+ PackageDatabaseEntryCollection::ConstPointer c(
+ DefaultEnvironment::get_instance()->package_database()->query(_options.headers, is_installed_only));
+
+ if (c->empty())
+ return false;
+
+ return (! DefaultEnvironment::get_instance()->query_use(UseFlagName("nocxx"), &(*c->last())));
+}
diff --git a/src/contrarius/stage.hh b/src/contrarius/stage.hh
new file mode 100644
index 0000000..098d7c8
--- /dev/null
+++ b/src/contrarius/stage.hh
@@ -0,0 +1,174 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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_SRC_CONTRARIUS_STAGE_HH
+#define PALUDIS_GUARD_SRC_CONTRARIUS_STAGE_HH 1
+
+#include <paludis/name.hh>
+#include <paludis/host_tuple_name.hh>
+#include <paludis/dep_atom.hh>
+#include <paludis/tasks/stage_builder_task.hh>
+
+#include <string>
+
+namespace paludis
+{
+#include <src/contrarius/contrarius_stage_options-sr.hh>
+
+ class ContrariusStage :
+ public StageBase
+ {
+ protected:
+ ContrariusStageOptions _options;
+
+ public:
+ ContrariusStage(const ContrariusStageOptions & o) :
+ _options(o)
+ {
+ }
+ };
+
+ class BinutilsStage :
+ public ContrariusStage
+ {
+ public:
+ BinutilsStage(const ContrariusStageOptions & o) :
+ ContrariusStage(o)
+ {
+ }
+
+ virtual int build(const StageOptions &) const;
+
+ virtual std::string description() const
+ {
+ return "Building the GNU binutils (" + stringify(*_options.binutils)
+ + ") as part of cross toolchain";
+ };
+
+ virtual bool is_rebuild() const;
+
+ virtual std::string short_name() const
+ {
+ return "cross-binutils stage";
+ }
+ };
+
+ class KernelHeadersStage :
+ public ContrariusStage
+ {
+ public:
+ KernelHeadersStage(const ContrariusStageOptions & o) :
+ ContrariusStage(o)
+ {
+ }
+
+ virtual int build(const StageOptions &) const;
+
+ virtual std::string description() const
+ {
+ return "Building the kernel headers (" + stringify(*_options.headers)
+ + ") as part of cross toolchain";
+ };
+
+ virtual bool is_rebuild() const;
+
+ virtual std::string short_name() const
+ {
+ return "cross-kernel-headers stage";
+ }
+ };
+
+ class MinimalStage :
+ public ContrariusStage
+ {
+ public:
+ MinimalStage(const ContrariusStageOptions & o) :
+ ContrariusStage(o)
+ {
+ }
+
+ virtual int build(const StageOptions &) const;
+
+ virtual std::string description() const
+ {
+ return "Building a minimal GNU C compiler (" + stringify(*_options.gcc)
+ + ") as part of the cross toolchain";
+ };
+
+ virtual bool is_rebuild() const;
+
+ virtual std::string short_name() const
+ {
+ return "cross-minimal-gcc stage";
+ }
+ };
+
+ class LibCStage :
+ public ContrariusStage
+ {
+ public:
+ LibCStage(const ContrariusStageOptions & o) :
+ ContrariusStage(o)
+ {
+ }
+
+ virtual int build(const StageOptions &) const;
+
+ virtual std::string description() const
+ {
+ return "Building C standard library (" + stringify(*_options.gcc)
+ + ") as part of the cross toolchain";
+ };
+
+ virtual bool is_rebuild() const;
+
+ virtual std::string short_name() const
+ {
+ return "cross-libc stage";
+ }
+ };
+
+
+ class FullStage :
+ public ContrariusStage
+ {
+ public:
+ FullStage(const ContrariusStageOptions & o) :
+ ContrariusStage(o)
+ {
+ }
+
+ virtual int build(const StageOptions &) const;
+
+ virtual std::string description() const
+ {
+ return "Building full GNU compiler collection (" + stringify(*_options.gcc)
+ + ") as part of the cross toolchain";
+ };
+
+ virtual bool is_rebuild() const;
+
+ virtual std::string short_name() const
+ {
+ return "cross-gcc stage";
+ }
+ };
+}
+
+#endif
diff --git a/src/contrarius/stage_builder.cc b/src/contrarius/stage_builder.cc
new file mode 100644
index 0000000..487cbae
--- /dev/null
+++ b/src/contrarius/stage_builder.cc
@@ -0,0 +1,90 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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/tasks/stage_builder_task.hh>
+#include <src/contrarius/stage.hh>
+#include <src/contrarius/stage_builder.hh>
+#include <src/colour.hh>
+
+#include <iostream>
+#include <list>
+#include <string>
+
+using namespace paludis;
+using std::cout;
+using std::endl;
+
+void
+OurStageBuilderTask::on_build_all_pre()
+{
+ cout << endl << colour(cl_heading, "These stages will be built:")
+ << endl << endl;
+
+ int num_stages(0), num_rebuilds(0);
+ for (StageIterator s(begin_stages()), s_end(end_stages()) ; s != s_end ; s++)
+ {
+ cout << "o " << colour(cl_key_name, (*s)->short_name()) << endl
+ << " " << colour(cl_tag, (*s)->description()) << endl;
+ ++num_stages;
+ if ((*s)->is_rebuild())
+ ++num_rebuilds;
+ }
+
+ cout << endl << "Total: " << num_stages << " Stage" << (num_stages > 1 ? "s" : "")
+ << " (" << num_rebuilds << " rebuild)" << endl;
+
+ cout << endl;
+}
+
+void
+OurStageBuilderTask::on_build_pre(StageBase::ConstPointer s)
+{
+ cout << colour(cl_heading, "Contents of stage ")
+ << colour(cl_stage_short_name, s->short_name()) << endl;
+}
+
+void
+OurStageBuilderTask::on_build_post(StageBase::ConstPointer)
+{
+}
+
+void
+OurStageBuilderTask::on_build_fail(StageBase::ConstPointer s, const StageBuildError & e)
+{
+ cout << "Build of stage '" << s->short_name() << "' failed:" << endl;
+ cout << "Error: " << e.message() << endl << endl;
+}
+
+void
+OurStageBuilderTask::on_build_succeed(StageBase::ConstPointer s)
+{
+ cout << "Build of stage '" << s->short_name() << "' succeeded." << endl << endl;
+}
+
+void
+OurStageBuilderTask::on_build_skipped(StageBase::ConstPointer s)
+{
+ cout << "Skipped rebuild of stage '" << s->short_name() << "'" << endl << endl;
+}
+
+void
+OurStageBuilderTask::on_build_all_post()
+{
+ cout << endl;
+}
diff --git a/src/contrarius/stage_builder.hh b/src/contrarius/stage_builder.hh
new file mode 100644
index 0000000..da147d8
--- /dev/null
+++ b/src/contrarius/stage_builder.hh
@@ -0,0 +1,48 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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_SRC_CONTRARIUS_STAGE_BUILDER_HH
+#define PALUDIS_GUARD_SRC_CONTRARIUS_STAGE_BUILDER_HH 1
+
+#include <paludis/tasks/stage_builder_task.hh>
+#include <src/contrarius/stage.hh>
+#include <string>
+
+namespace paludis
+{
+ class OurStageBuilderTask :
+ public StageBuilderTask
+ {
+ public:
+ OurStageBuilderTask(const StageOptions & o) :
+ StageBuilderTask(o)
+ {
+ }
+
+ virtual void on_build_all_pre();
+ virtual void on_build_pre(StageBase::ConstPointer);
+ virtual void on_build_post(StageBase::ConstPointer);
+ virtual void on_build_fail(StageBase::ConstPointer, const StageBuildError &);
+ virtual void on_build_succeed(StageBase::ConstPointer);
+ virtual void on_build_skipped(StageBase::ConstPointer);
+ virtual void on_build_all_post();
+ };
+}
+
+#endif