diff options
author | 2006-10-11 20:56:59 +0000 | |
---|---|---|
committer | 2006-10-11 20:56:59 +0000 | |
commit | e3b86134db7baada7b3a1e779e7d6d046ab53a1a (patch) | |
tree | 6acb3c0de68e1b95dbba8f0e00f770b8f31e4bac /0.8.0/src | |
parent | ab9cdb1150d97449e857cd55fe706377c9ab2422 (diff) | |
download | paludis-e3b86134db7baada7b3a1e779e7d6d046ab53a1a.tar.gz paludis-e3b86134db7baada7b3a1e779e7d6d046ab53a1a.tar.xz |
Tag release 0.8.00.8.0
Diffstat (limited to '0.8.0/src')
100 files changed, 10646 insertions, 0 deletions
diff --git a/0.8.0/src/Makefile.am b/0.8.0/src/Makefile.am new file mode 100644 index 000000000..796c8b4aa --- /dev/null +++ b/0.8.0/src/Makefile.am @@ -0,0 +1,9 @@ +SUBDIRS = . paludis gtkpaludis qualudis adjutrix + +CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda +MAINTAINERCLEANFILES = Makefile.in + +noinst_LIBRARIES = libcolour.a +libcolour_a_SOURCES = colour.cc colour.hh +AM_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src @PALUDIS_CXXFLAGS@ + diff --git a/0.8.0/src/adjutrix/Makefile.am b/0.8.0/src/adjutrix/Makefile.am new file mode 100644 index 000000000..11eac6e7e --- /dev/null +++ b/0.8.0/src/adjutrix/Makefile.am @@ -0,0 +1,88 @@ +AM_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src @PALUDIS_CXXFLAGS@ +DEFS= \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DDATADIR=\"$(datadir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DLIBDIR=\"$(libdir)\" + +SUBDIRS = . + +bin_PROGRAMS = adjutrix +noinst_PROGRAMS = man-adjutrix + +man_MANS = adjutrix.1 + +adjutrix.1 : man-adjutrix + ./man-adjutrix | tee $@ | sed -e 's/^/ /' + +man_adjutrix_SOURCES = \ + man_adjutrix.cc \ + command_line.hh \ + command_line.cc + +man_adjutrix_LDADD = \ + $(top_builddir)/paludis/args/libpaludisargs.la \ + $(top_builddir)/paludis/util/libpaludisutil.la \ + $(top_builddir)/src/libcolour.a \ + $(DYNAMIC_LD_LIBS) + +adjutrix_SOURCES = \ + command_line.hh command_line.cc \ + find_stable_candidates.hh find_stable_candidates.cc \ + find_dropped_keywords.hh find_dropped_keywords.cc \ + find_insecure_packages.hh find_insecure_packages.cc \ + find_reverse_deps.hh find_reverse_deps.cc \ + keywords_graph.hh keywords_graph.cc \ + display_profiles_use.hh display_profiles_use.cc \ + display_default_system_resolution.hh display_default_system_resolution.cc \ + adjutrix.cc + +adjutrix_LDADD = \ + $(top_builddir)/paludis/repositories/portage/libpaludisportagerepository.la \ + $(top_builddir)/paludis/tasks/libpaludistasks.a \ + $(top_builddir)/paludis/libpaludis.la \ + $(top_builddir)/paludis/args/libpaludisargs.la \ + $(top_builddir)/paludis/util/libpaludisutil.la \ + $(top_builddir)/paludis/environment/no_config/libpaludisnoconfigenvironment.la \ + $(top_builddir)/src/libcolour.a \ + $(DYNAMIC_LD_LIBS) + +TESTS_ENVIRONMENT = env \ + TEST_SCRIPT_DIR="$(srcdir)/" \ + PALUDIS_NO_GLOBAL_HOOKS="yes" \ + PALUDIS_NO_XTERM_TITLES="yes" \ + PALUDIS_EBUILD_DIR="`$(top_srcdir)/ebuild/utils/canonicalise $(top_srcdir)/ebuild/`" \ + PALUDIS_EBUILD_DIR_FALLBACK="`$(top_srcdir)/ebuild/utils/canonicalise $(top_builddir)/ebuild/`" \ + PALUDIS_REPOSITORY_SO_DIR="`$(top_srcdir)/ebuild/utils/canonicalise $(top_builddir)/paludis/repositories`" \ + SYSCONFDIR="$(sysconfdir)" \ + bash $(top_srcdir)/test/run_test.sh bash + +TESTS = version_TEST help_TEST find_stable_candidates_TEST + +EXTRA_DIST = \ + $(man_MANS) \ + $(TESTS) \ + find_stable_candidates-sr.hh find_stable_candidates-sr.cc find_stable_candidates.sr \ + find_dropped_keywords-sr.hh find_dropped_keywords-sr.cc find_dropped_keywords.sr \ + find_stable_candidates_TEST_setup.sh find_stable_candidates_TEST_cleanup.sh + +CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda +DISTCLEANFILES = $(man_MANS) find_stable_candidates-sr.hh find_stable_candidates-sr.cc +MAINTAINERCLEANFILES = Makefile.in +BUILT_SOURCES = \ + find_stable_candidates-sr.hh find_stable_candidates-sr.cc \ + find_dropped_keywords-sr.hh find_dropped_keywords-sr.cc + +find_stable_candidates-sr.hh : find_stable_candidates.sr $(top_srcdir)/misc/make_sr.bash + $(top_srcdir)/misc/make_sr.bash --header $(srcdir)/find_stable_candidates.sr > $@ + +find_stable_candidates-sr.cc : find_stable_candidates.sr $(top_srcdir)/misc/make_sr.bash + $(top_srcdir)/misc/make_sr.bash --source $(srcdir)/find_stable_candidates.sr > $@ + +find_dropped_keywords-sr.hh : find_dropped_keywords.sr $(top_srcdir)/misc/make_sr.bash + $(top_srcdir)/misc/make_sr.bash --header $(srcdir)/find_dropped_keywords.sr > $@ + +find_dropped_keywords-sr.cc : find_dropped_keywords.sr $(top_srcdir)/misc/make_sr.bash + $(top_srcdir)/misc/make_sr.bash --source $(srcdir)/find_dropped_keywords.sr > $@ + + diff --git a/0.8.0/src/adjutrix/adjutrix.cc b/0.8.0/src/adjutrix/adjutrix.cc new file mode 100644 index 000000000..8737fbd33 --- /dev/null +++ b/0.8.0/src/adjutrix/adjutrix.cc @@ -0,0 +1,278 @@ +/* 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 "colour.hh" +#include "command_line.hh" +#include "find_stable_candidates.hh" +#include "find_dropped_keywords.hh" +#include "find_insecure_packages.hh" +#include "find_reverse_deps.hh" +#include "keywords_graph.hh" +#include "display_profiles_use.hh" +#include "display_default_system_resolution.hh" + +#include <paludis/about.hh> +#include <paludis/util/join.hh> +#include <paludis/util/log.hh> +#include <paludis/util/fs_entry.hh> +#include <paludis/environment/no_config/no_config_environment.hh> +#include <iostream> + +using namespace paludis; +using std::cout; +using std::cerr; +using std::endl; + +namespace +{ + FSEntry + get_location_and_add_filters() + { + Context context("When determining tree location:"); + + if (CommandLine::get_instance()->a_repository_directory.specified()) + return FSEntry(CommandLine::get_instance()->a_repository_directory.argument()); + + if ((FSEntry::cwd() / "profiles").is_directory()) + return FSEntry::cwd(); + if ((FSEntry::cwd().dirname() / "profiles").is_directory()) + { + CommandLine::get_instance()->a_category.add_argument(FSEntry::cwd().basename()); + CommandLine::get_instance()->a_category.set_specified(true); + return FSEntry::cwd().dirname(); + } + if ((FSEntry::cwd().dirname().dirname() / "profiles").is_directory()) + { + CommandLine::get_instance()->a_package.add_argument(FSEntry::cwd().basename()); + CommandLine::get_instance()->a_package.set_specified(true); + CommandLine::get_instance()->a_category.add_argument(FSEntry::cwd().dirname().basename()); + CommandLine::get_instance()->a_category.set_specified(true); + return FSEntry::cwd().dirname().dirname(); + } + + throw ConfigurationError("Cannot find tree location (try specifying --repository-dir)"); + } + + void display_version() + { + cout << "adjutrix " << 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 << "DATADIR: " << DATADIR << endl; + cout << "LIBDIR: " << LIBDIR << endl; + cout << "LIBEXECDIR: " << LIBEXECDIR << endl; + cout << "SYSCONFDIR: " << SYSCONFDIR << endl; + cout << "stdlib: " +#if defined(__GLIBCXX__) +# define XSTRINGIFY(x) #x +# define STRINGIFY(x) XSTRINGIFY(x) + << "GNU libstdc++ " << STRINGIFY(__GLIBCXX__) +#endif + << endl; + } + + struct DoVersion + { + }; +} + +int +main(int argc, char *argv[]) +{ + Context context("In program " + join(argv, argv + argc, " ") + ":"); + + try + { + CommandLine::get_instance()->run(argc, argv); + set_use_colour(! CommandLine::get_instance()->a_no_color.specified()); + + if (CommandLine::get_instance()->a_help.specified()) + throw DoHelp(); + + if (CommandLine::get_instance()->a_version.specified()) + throw DoVersion(); + + 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 (1 != ( + CommandLine::get_instance()->a_find_stable_candidates.specified() + + CommandLine::get_instance()->a_find_dropped_keywords.specified() + + CommandLine::get_instance()->a_find_insecure_packages.specified() + + CommandLine::get_instance()->a_keywords_graph.specified() + + CommandLine::get_instance()->a_reverse_deps.specified() + + CommandLine::get_instance()->a_display_profiles_use.specified() + + CommandLine::get_instance()->a_display_default_system_resolution.specified() + )) + throw DoHelp("you should specify exactly one action"); + + NoConfigEnvironment env(NoConfigEnvironmentParams::create() + .repository_dir(get_location_and_add_filters()) + .accept_unstable(CommandLine::get_instance()->a_unstable.specified())); + + if (CommandLine::get_instance()->a_find_stable_candidates.specified()) + { + if (1 != std::distance(CommandLine::get_instance()->begin_parameters(), + CommandLine::get_instance()->end_parameters())) + throw DoHelp("find-stable-candidates action takes exactly one parameter (the target arch)"); + + do_find_stable_candidates(env); + return EXIT_SUCCESS; + } + + if (CommandLine::get_instance()->a_find_dropped_keywords.specified()) + { + if (1 != std::distance(CommandLine::get_instance()->begin_parameters(), + CommandLine::get_instance()->end_parameters())) + throw DoHelp("find-dropped-keywords action takes exactly one parameter (the target arch)"); + + do_find_dropped_keywords(env); + return EXIT_SUCCESS; + } + + if (CommandLine::get_instance()->a_find_insecure_packages.specified()) + { + if (CommandLine::get_instance()->begin_parameters() != + CommandLine::get_instance()->end_parameters()) + throw DoHelp("find-dropped-keywords action takes no parameters"); + + do_find_insecure_packages(env); + return EXIT_SUCCESS; + } + + + if (CommandLine::get_instance()->a_keywords_graph.specified()) + { + if (CommandLine::get_instance()->begin_parameters() != + CommandLine::get_instance()->end_parameters()) + throw DoHelp("keywords-graph action takes no parameters"); + + do_keywords_graph(env); + return EXIT_SUCCESS; + } + + if (CommandLine::get_instance()->a_reverse_deps.specified()) + { + if (1 != std::distance(CommandLine::get_instance()->begin_parameters(), + CommandLine::get_instance()->end_parameters())) + throw DoHelp("reverse-deps action takes exactly one parameter (the target dep)"); + + return do_find_reverse_deps(env); + } + + if (CommandLine::get_instance()->a_display_profiles_use.specified()) + { + if (CommandLine::get_instance()->begin_parameters() != + CommandLine::get_instance()->end_parameters()) + throw DoHelp("display-profiles-use action takes no parameters"); + + do_display_profiles_use(env); + return EXIT_SUCCESS; + } + + if (CommandLine::get_instance()->a_display_default_system_resolution.specified()) + { + if (CommandLine::get_instance()->begin_parameters() != + CommandLine::get_instance()->end_parameters()) + throw DoHelp("display-default-system-resolution action takes no parameters"); + + return do_display_default_system_resolution(env); + } + + throw InternalError(__PRETTY_FUNCTION__, "no action?"); + } + catch (const DoVersion &) + { + display_version(); + 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 << 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/0.8.0/src/adjutrix/command_line.cc b/0.8.0/src/adjutrix/command_line.cc new file mode 100644 index 000000000..c0b5c9180 --- /dev/null +++ b/0.8.0/src/adjutrix/command_line.cc @@ -0,0 +1,140 @@ +/* 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 "command_line.hh" + +CommandLine::CommandLine() : + ArgsHandler(), + + tree_action_args(this, "Tree-Oriented Actions", + "Selects which basic tree-oriented action to perform. Exactly one action should " + "be specified."), + + a_find_stable_candidates(&tree_action_args, + "find-stable-candidates", 's', "Search for stable package candidates"), + a_find_dropped_keywords(&tree_action_args, + "find-dropped-keywords", 'd', "Search for packages where keywords have been dropped"), + a_find_insecure_packages(&tree_action_args, + "find-insecure-packages", 'i', "Search for packages marked as insecure by a GLSA"), + a_keywords_graph(&tree_action_args, + "keyword-graph", 'k', "Display keywords graphically"), + a_reverse_deps(&tree_action_args, + "reverse-deps", 'r', "Find all package that depend on a given dep atom"), + + profile_action_args(this, "Profile-Oriented Actions", + "Selects which basic profile-oriented action to perform. Exactly one action should " + "be specified."), + + a_display_profiles_use(&profile_action_args, + "display-profiles-use", 'u', "Display USE information for all profiles"), + a_display_default_system_resolution(&profile_action_args, + "display-default-system-resolution", 'S', "Display package names and versions that are included in " + "the default resolution of the system set"), + + general_action_args(this, "General Actions", + "Selects which basic general action to perform. Exactly one action should " + "be specified."), + + a_version(&general_action_args, + "version", 'V', "Display program version"), + a_help(&general_action_args, + "help", 'h', "Display program help"), + + general_args(this, "General options", + "Options which are relevant for most or all actions."), + a_log_level(&general_args, "log-level", '\0', "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"), + "qa"), + a_no_colour(&general_args, "no-colour", '\0', "Do not use colour"), + a_no_color(&a_no_colour, "no-color"), + + a_repository_directory(&general_args, "repository-dir", 'D', + "Where to find the repository (default: detected from ./ or ../ or ../..)"), + + tree_args(this, "Tree action options", + "Options which are relevant for tree actions."), + a_category(&tree_args, "category", 'C', + "Matches with this category name only (may be specified multiple times)"), + a_package(&tree_args, "package", 'P', + "Matches with this package name only (may be specified multiple times)"), + + profile_args(this, "Profile action options", + "Options which are relevant for profile actions."), + a_profile(&profile_args, "profile", 'p', + "Display results for this profile path, rather than all profiles (may be specified multiple times)"), + a_unstable(&profile_args, "unstable", 'U', + "Accept ~arch as well as arch") +{ + add_usage_line("--find-stable-candidates arch [ --repository-dir /path ] " + "[ --category app-misc --category sys-apps ... ] " + "[ --package foo --package fnord ... ] "); + add_usage_line("--find-dropped-keywords arch [ --repository-dir /path ] " + "[ --category app-misc --category sys-apps ... ] " + "[ --package foo --package fnord ... ] "); + add_usage_line("--find-insecure-packages [ --repository-dir /path ] " + "[ --category app-misc --category sys-apps ... ] " + "[ --package foo --package fnord ... ] "); + add_usage_line("--keywords-graph [ --repository-dir /path ] " + "[ --category app-misc --category sys-apps ... ] " + "[ --package foo --package fnord ... ]"); + add_usage_line("--display-profiles-use [ --profile default-linux/x86/2006.0 " + "--profile default-linux/x86/2006.1 ... ] [ --repository-dir /path ]"); + + add_usage_line("--version"); + add_usage_line("--help"); + + add_enviromnent_variable("PALUDIS_EBUILD_DIR", "Where to look for ebuild.bash and related " + "utilities."); + add_enviromnent_variable("PALUDIS_REPOSITORY_SO_DIR", "Where to look for repository .so " + "files."); +} + +std::string +CommandLine::app_name() const +{ + return "adjutrix"; +} + +std::string +CommandLine::app_synopsis() const +{ + return "A tool for arch teams"; +} + +std::string +CommandLine::app_description() const +{ + return + "adjutrix provides a number of utilities that may be useful for arch teams." + "\n\n" + "The --repository-dir switch can be used to tell adjutrix where to find " + "the repository. If this switch is not used, adjutrix will check the current " + "directory, the parent directory and the parent's parent directory for " + "something resembling a profile root. If run inside a package or category " + "directory, filtering in the style of --package and --category is carried " + "out automatically for the current package or category."; +} + +CommandLine::~CommandLine() +{ +} + diff --git a/0.8.0/src/adjutrix/command_line.hh b/0.8.0/src/adjutrix/command_line.hh new file mode 100644 index 000000000..7414728e8 --- /dev/null +++ b/0.8.0/src/adjutrix/command_line.hh @@ -0,0 +1,126 @@ +/* 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_SRC_ARCHTOOL_COMMAND_LINE_HH +#define PALUDIS_GUARD_SRC_ARCHTOOL_COMMAND_LINE_HH 1 + +#include <paludis/args/args.hh> +#include <paludis/util/instantiation_policy.hh> + +/** \file + * Declarations for the CommandLine class. + */ + +/** + * Our command line. + */ +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 tree_action_args; + paludis::args::SwitchArg a_find_stable_candidates; + paludis::args::SwitchArg a_find_dropped_keywords; + paludis::args::SwitchArg a_find_insecure_packages; + paludis::args::SwitchArg a_keywords_graph; + paludis::args::SwitchArg a_reverse_deps; + + paludis::args::ArgsGroup profile_action_args; + paludis::args::SwitchArg a_display_profiles_use; + paludis::args::SwitchArg a_display_default_system_resolution; + + paludis::args::ArgsGroup general_action_args; + paludis::args::SwitchArg a_version; + paludis::args::SwitchArg a_help; + + /// \name General arguments + ///{ + + /// General arguments. + paludis::args::ArgsGroup general_args; + + paludis::args::EnumArg a_log_level; + paludis::args::SwitchArg a_no_colour; + paludis::args::AliasArg a_no_color; + + paludis::args::StringArg a_repository_directory; + + ///} + + + ///\name Tree arguments + ///\{ + + paludis::args::ArgsGroup tree_args; + + paludis::args::StringSetArg a_category; + paludis::args::StringSetArg a_package; + + ///\} + + ///\name Profile arguments + ///\{ + + paludis::args::ArgsGroup profile_args; + + paludis::args::StringSetArg a_profile; + paludis::args::SwitchArg a_unstable; + + ///\} + +}; + +/** + * Show the help message. + */ +struct DoHelp +{ + const std::string message; + + DoHelp(const std::string & m = "") : + message(m) + { + } +}; + +#endif diff --git a/0.8.0/src/adjutrix/display_default_system_resolution.cc b/0.8.0/src/adjutrix/display_default_system_resolution.cc new file mode 100644 index 000000000..7ccbf4544 --- /dev/null +++ b/0.8.0/src/adjutrix/display_default_system_resolution.cc @@ -0,0 +1,135 @@ +/* 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 "display_default_system_resolution.hh" +#include "command_line.hh" +#include "colour.hh" +#include <paludis/config_file.hh> +#include <paludis/util/log.hh> +#include <paludis/util/tokeniser.hh> +#include <paludis/util/dir_iterator.hh> +#include <paludis/util/is_file_with_extension.hh> +#include <paludis/util/strip.hh> +#include <paludis/dep_list.hh> + +#include <iostream> +#include <iomanip> +#include <vector> +#include <cstdlib> +#include <set> +#include <map> + +using namespace paludis; +using std::cout; +using std::cerr; +using std::endl; + +using namespace paludis; + +namespace +{ + int + display_default_system_resolution(const NoConfigEnvironment & env, const std::string & desc, + const FSEntry & profile) + { + int return_code(0); + + Context context("When displaying system resolution for '" + stringify(desc) + "' at '" + + stringify(profile) + "':"); + + std::string display_profile(stringify(profile)), display_profile_chop( + stringify(env.main_repository_dir() / "profiles")); + if (0 == display_profile.compare(0, display_profile_chop.length(), display_profile_chop)) + { + display_profile.erase(0, display_profile_chop.length()); + if (0 == display_profile.compare(0, 1, "/")) + display_profile.erase(0, 1); + if (display_profile.empty()) + display_profile = "/"; + } + + cout << std::left << std::setw(20) << (desc + ":") << display_profile << endl; + + DepListOptions d_options; + d_options.circular = dl_circular_discard; + DepList d(&env, d_options); + + try + { + d.add(env.package_set("system")); + + for (DepList::Iterator e(d.begin()), e_end(d.end()) ; e != e_end ; ++e) + cout << " " << e->package << ":" << e->metadata->slot << endl; + } + catch (const NoSuchPackageError & e) + { + cout << endl; + cerr << "Query error:" << endl; + cerr << " * " << e.backtrace("\n * "); + cerr << "No such package '" << e.name() << "'" << 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; + } + + cout << endl; + + return return_code; + } +} + +int do_display_default_system_resolution(NoConfigEnvironment & env) +{ + int return_code(0); + + Context context("When performing display-default-system-resolution action:"); + + if (CommandLine::get_instance()->a_profile.args_begin() == + CommandLine::get_instance()->a_profile.args_end()) + { + for (NoConfigEnvironment::ProfilesIterator p(env.begin_profiles()), p_end(env.end_profiles()) ; + p != p_end ; ++p) + { + env.set_profile(p->path); + return_code |= display_default_system_resolution(env, p->arch + "." + p->status, p->path); + } + } + else + { + for (args::StringSetArg::Iterator i(CommandLine::get_instance()->a_profile.args_begin()), + i_end(CommandLine::get_instance()->a_profile.args_end()) ; i != i_end ; ++i) + { + env.set_profile(env.main_repository_dir() / "profiles" / (*i)); + return_code |= display_default_system_resolution(env, *i, env.main_repository_dir() / "profiles" / *i); + } + } + + return return_code; +} + + diff --git a/0.8.0/src/adjutrix/display_default_system_resolution.hh b/0.8.0/src/adjutrix/display_default_system_resolution.hh new file mode 100644 index 000000000..6d6c3402c --- /dev/null +++ b/0.8.0/src/adjutrix/display_default_system_resolution.hh @@ -0,0 +1,27 @@ +/* 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_SRC_ADJUTRIX_DISPLAY_DEFAULT_SYSTEM_RESOLUTION_HH +#define PALUDIS_GUARD_SRC_ADJUTRIX_DISPLAY_DEFAULT_SYSTEM_RESOLUTION_HH 1 + +#include <paludis/environment/no_config/no_config_environment.hh> + +int do_display_default_system_resolution(paludis::NoConfigEnvironment & env); + +#endif diff --git a/0.8.0/src/adjutrix/display_profiles_use.cc b/0.8.0/src/adjutrix/display_profiles_use.cc new file mode 100644 index 000000000..cce7eac3a --- /dev/null +++ b/0.8.0/src/adjutrix/display_profiles_use.cc @@ -0,0 +1,176 @@ +/* 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 "display_profiles_use.hh" +#include "command_line.hh" +#include "colour.hh" +#include <paludis/config_file.hh> +#include <paludis/util/log.hh> +#include <paludis/util/tokeniser.hh> +#include <paludis/util/dir_iterator.hh> +#include <paludis/util/is_file_with_extension.hh> +#include <paludis/util/strip.hh> + +#include <iostream> +#include <iomanip> +#include <vector> +#include <cstdlib> +#include <set> +#include <map> + +using namespace paludis; +using std::cout; +using std::cerr; +using std::endl; + +using namespace paludis; + +namespace +{ + std::string + upperify(const std::string & s) + { + std::string result; + std::transform(s.begin(), s.end(), std::back_inserter(result), &::toupper); + return result; + } + + void + display_profiles_use(const NoConfigEnvironment & env, const std::string & desc, + const FSEntry & profile, const std::set<UseFlagName> & all_use, + const std::multimap<std::string, UseFlagName> & all_use_expand_flags) + { + Context context("When displaying profile use for '" + stringify(desc) + "' at '" + + stringify(profile) + "':"); + + std::string display_profile(stringify(profile)), display_profile_chop( + stringify(env.main_repository_dir() / "profiles")); + if (0 == display_profile.compare(0, display_profile_chop.length(), display_profile_chop)) + { + display_profile.erase(0, display_profile_chop.length()); + if (0 == display_profile.compare(0, 1, "/")) + display_profile.erase(0, 1); + if (display_profile.empty()) + display_profile = "/"; + } + + cout << std::left << std::setw(20) << (desc + ":") << display_profile << endl; + + cout << std::setw(20) << "USE:"; + + PackageDatabaseEntry e(QualifiedPackageName("dummy-category/dummy-package"), VersionSpec("0"), + env.package_database()->favourite_repository()); + for (std::set<UseFlagName>::const_iterator u(all_use.begin()), u_end(all_use.end()) ; + u != u_end ; ++u) + if (env.query_use(*u, &e)) + cout << *u << " "; + + std::string current_prefix("not on a boat"); + for (std::multimap<std::string, UseFlagName>::const_iterator u(all_use_expand_flags.begin()), + u_end(all_use_expand_flags.end()) ; u != u_end ; ++u) + { + if (u->first != current_prefix) + cout << endl << std::setw(20) << (upperify(stringify(u->first)) + ":"); + current_prefix = u->first; + + if (env.query_use(UseFlagName(current_prefix + "_" + stringify(u->second)), &e)) + cout << u->second << " "; + } + + cout << endl << endl; + } +} + +void do_display_profiles_use(NoConfigEnvironment & env) +{ + Context context("When performing display-profiles-use action:"); + + std::set<UseFlagName> all_use_flags; + { + LineConfigFile use_desc(env.main_repository_dir() / "profiles"/ "use.desc"); + for (LineConfigFile::Iterator line(use_desc.begin()), line_end(use_desc.end()) ; + line != line_end ; ++line) + { + std::vector<std::string> tokens; + WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens)); + + if (tokens.size() < 2) + { + Log::get_instance()->message(ll_warning, lc_context, "Skipping invalid line '" + + *line + "'"); + continue; + } + + all_use_flags.insert(UseFlagName(tokens.at(0))); + } + } + + std::multimap<std::string, UseFlagName> all_use_expand_flags; + { + for (DirIterator d(env.main_repository_dir() / "profiles" / "desc"), d_end ; + d != d_end ; ++d) + { + if (! IsFileWithExtension(".desc")(*d)) + continue; + + std::string prefix(strip_trailing_string(d->basename(), ".desc")); + + LineConfigFile use_desc(*d); + for (LineConfigFile::Iterator line(use_desc.begin()), line_end(use_desc.end()) ; + line != line_end ; ++line) + { + std::vector<std::string> tokens; + WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens)); + + if (tokens.size() < 2) + { + Log::get_instance()->message(ll_warning, lc_context, "Skipping invalid line '" + + *line + "'"); + continue; + } + + all_use_expand_flags.insert(std::make_pair(prefix, UseFlagName(tokens.at(0)))); + } + } + } + + if (CommandLine::get_instance()->a_profile.args_begin() == + CommandLine::get_instance()->a_profile.args_end()) + { + for (NoConfigEnvironment::ProfilesIterator p(env.begin_profiles()), p_end(env.end_profiles()) ; + p != p_end ; ++p) + { + env.set_profile(p); + display_profiles_use(env, p->arch + "." + p->status, p->path, + all_use_flags, all_use_expand_flags); + } + } + else + { + for (args::StringSetArg::Iterator i(CommandLine::get_instance()->a_profile.args_begin()), + i_end(CommandLine::get_instance()->a_profile.args_end()) ; i != i_end ; ++i) + { + env.set_profile(env.main_repository_dir() / "profiles" / (*i)); + display_profiles_use(env, *i, env.main_repository_dir() / + "profiles" / *i, all_use_flags, all_use_expand_flags); + } + } +} + + diff --git a/0.8.0/src/adjutrix/display_profiles_use.hh b/0.8.0/src/adjutrix/display_profiles_use.hh new file mode 100644 index 000000000..8a5b4e095 --- /dev/null +++ b/0.8.0/src/adjutrix/display_profiles_use.hh @@ -0,0 +1,27 @@ +/* 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_SRC_ADJUTRIX_DISPLAY_PROFILES_USE_HH +#define PALUDIS_GUARD_SRC_ADJUTRIX_DISPLAY_PROFILES_USE_HH 1 + +#include <paludis/environment/no_config/no_config_environment.hh> + +void do_display_profiles_use(paludis::NoConfigEnvironment & env); + +#endif diff --git a/0.8.0/src/adjutrix/find_dropped_keywords.cc b/0.8.0/src/adjutrix/find_dropped_keywords.cc new file mode 100644 index 000000000..e8e26434c --- /dev/null +++ b/0.8.0/src/adjutrix/find_dropped_keywords.cc @@ -0,0 +1,208 @@ +/* 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 "find_dropped_keywords.hh" +#include "command_line.hh" + +#include <paludis/util/tokeniser.hh> +#include <paludis/util/compare.hh> + +#include <set> +#include <map> +#include <iostream> +#include <iomanip> +#include <algorithm> + +using namespace paludis; +using std::cout; +using std::cerr; +using std::endl; + +namespace +{ + +#include "find_dropped_keywords-sr.hh" +#include "find_dropped_keywords-sr.cc" + + static const int col_width_package = 30; + static const int col_width_best_keyworded = 20; + static const int col_width_best_anywhere = 20; + + void + write_repository_header(const KeywordName & keyword, const RepositoryName & repo) + { + std::string s("Dropped keywords for '" + stringify(repo) + "' on '" + + stringify(keyword) + "'"); + cout << std::string(s.length(), '=') << endl; + cout << s << endl; + cout << std::string(s.length(), '=') << endl; + cout << endl; + + cout << std::left + << std::setw(col_width_package) << "category/package (:slot)" + << std::setw(col_width_best_keyworded) << "best keyworded" + << std::setw(col_width_best_anywhere) << "best anywhere" + << endl; + + cout + << std::string(col_width_package - 1, '-') << " " + << std::string(col_width_best_keyworded - 1, '-') << " " + << std::string(col_width_best_anywhere - 1, '-') << " " + << endl; + } + + struct IsStableOrUnstableKeyword + { + bool operator() (const KeywordName & k) const + { + return stringify(k).at(0) != '-'; + } + }; + + void + write_package(const QualifiedPackageName & package, const SlotName & slot, + const VersionSpec & best_keyworded, const VersionSpec & best_anywhere) + { + static CategoryNamePart previous_category("not-on-a-boat"); + if (package.category != previous_category) + { + cout << std::setw(col_width_package) << (stringify(package.category) + "/") << endl; + previous_category = package.category; + } + + std::string p(stringify(package.package)); + if (SlotName("0") != slot) + p += ":" + stringify(slot); + cout << " " << std::setw(col_width_package - 2) << p; + + if (best_keyworded != VersionSpec("0")) + cout << std::setw(col_width_best_keyworded) << best_keyworded; + else + cout << std::setw(col_width_best_keyworded) << " "; + cout << std::setw(col_width_best_anywhere) << best_anywhere; + cout << endl; + } + + void + check_one_package(const Environment &, const KeywordName & keyword, + const Repository & repo, const QualifiedPackageName & package) + { + /* determine whether we have any interesting versions, and pick out + * slots where we do. for slots, we map slot to a pair (best stable + * version for us, best stable version for anyone). */ + + bool is_interesting(false); + VersionSpec worst_keyworded("99999999"); + typedef std::map<SlotName, VersionsEntry> VersionsInSlots; + VersionsInSlots versions_in_slots; + + VersionSpecCollection::ConstPointer versions(repo.version_specs(package)); + for (VersionSpecCollection::Iterator v(versions->begin()), v_end(versions->end()) ; + v != v_end ; ++v) + { + VersionMetadata::ConstPointer metadata(repo.version_metadata(package, *v)); + if (! metadata->get_ebuild_interface()) + continue; + + std::set<KeywordName> keywords; + WhitespaceTokeniser::get_instance()->tokenise(metadata->get_ebuild_interface()->keywords, + create_inserter<KeywordName>(std::inserter(keywords, keywords.end()))); + + /* ensure that there's an entry for this SLOT */ + versions_in_slots.insert(std::make_pair(metadata->slot, VersionsEntry( + VersionsEntry::create() + .best_keyworded(VersionSpec("0")) + .best_anywhere(VersionSpec("0"))))); + + if (keywords.end() != keywords.find(keyword) || + keywords.end() != keywords.find(KeywordName("~" + stringify(keyword)))) + { + is_interesting = true; + versions_in_slots.find(metadata->slot)->second.best_keyworded = + std::max(versions_in_slots.find(metadata->slot)->second.best_keyworded, *v); + worst_keyworded = std::min(worst_keyworded, *v); + } + + if (keywords.end() != std::find_if(keywords.begin(), keywords.end(), IsStableOrUnstableKeyword())) + versions_in_slots.find(metadata->slot)->second.best_anywhere = + std::max(versions_in_slots.find(metadata->slot)->second.best_anywhere, *v); + } + + if (! is_interesting) + return; + + /* for each slot, if there's a higher version on another arch, flag it */ + for (VersionsInSlots::const_iterator s(versions_in_slots.begin()), + s_end(versions_in_slots.end()) ; s != s_end ; ++s) + { + if (s->second.best_keyworded >= s->second.best_anywhere) + continue; + + if (s->second.best_anywhere < worst_keyworded) + continue; + + write_package(package, s->first, s->second.best_keyworded, s->second.best_anywhere); + } + } +} + +void do_find_dropped_keywords(const Environment & env) +{ + Context context("When performing find-dropped-keywords action:"); + + KeywordName keyword(*CommandLine::get_instance()->begin_parameters()); + + for (IndirectIterator<PackageDatabase::RepositoryIterator, const Repository> + r(env.package_database()->begin_repositories()), + r_end(env.package_database()->end_repositories()) ; r != r_end ; ++r) + { + if (r->name() == RepositoryName("virtuals")) + continue; + + write_repository_header(keyword, r->name()); + + CategoryNamePartCollection::ConstPointer cat_names(r->category_names()); + for (CategoryNamePartCollection::Iterator c(cat_names->begin()), c_end(cat_names->end()) ; + c != c_end ; ++c) + { + if (CommandLine::get_instance()->a_category.specified()) + if (CommandLine::get_instance()->a_category.args_end() == std::find( + CommandLine::get_instance()->a_category.args_begin(), + CommandLine::get_instance()->a_category.args_end(), + stringify(*c))) + continue; + + QualifiedPackageNameCollection::ConstPointer pkg_names(r->package_names(*c)); + for (QualifiedPackageNameCollection::Iterator p(pkg_names->begin()), p_end(pkg_names->end()) ; + p != p_end ; ++p) + { + if (CommandLine::get_instance()->a_package.specified()) + if (CommandLine::get_instance()->a_package.args_end() == std::find( + CommandLine::get_instance()->a_package.args_begin(), + CommandLine::get_instance()->a_package.args_end(), + stringify(p->package))) + continue; + + check_one_package(env, keyword, *r, *p); + } + } + } +} + + diff --git a/0.8.0/src/adjutrix/find_dropped_keywords.hh b/0.8.0/src/adjutrix/find_dropped_keywords.hh new file mode 100644 index 000000000..e6bbe2265 --- /dev/null +++ b/0.8.0/src/adjutrix/find_dropped_keywords.hh @@ -0,0 +1,28 @@ +/* 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_SRC_ARCHTOOL_FIND_DROPPED_KEYWORDS_HH +#define PALUDIS_GUARD_SRC_ARCHTOOL_FIND_DROPPED_KEYWORDS_HH 1 + +#include <paludis/environment.hh> + +void do_find_dropped_keywords(const paludis::Environment & env); + +#endif + diff --git a/0.8.0/src/adjutrix/find_dropped_keywords.sr b/0.8.0/src/adjutrix/find_dropped_keywords.sr new file mode 100644 index 000000000..b197b2ae5 --- /dev/null +++ b/0.8.0/src/adjutrix/find_dropped_keywords.sr @@ -0,0 +1,13 @@ +#!/bin/bash +# vim: set sw=4 sts=4 et : + +make_class_VersionsEntry() +{ + key best_keyworded VersionSpec + key best_anywhere VersionSpec + + allow_named_args +} + + + diff --git a/0.8.0/src/adjutrix/find_insecure_packages.cc b/0.8.0/src/adjutrix/find_insecure_packages.cc new file mode 100644 index 000000000..1409c694f --- /dev/null +++ b/0.8.0/src/adjutrix/find_insecure_packages.cc @@ -0,0 +1,162 @@ +/* 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 "find_insecure_packages.hh" +#include "command_line.hh" + +#include <paludis/util/tokeniser.hh> +#include <paludis/util/compare.hh> + +#include <set> +#include <map> +#include <iostream> +#include <iomanip> +#include <algorithm> + +using namespace paludis; +using std::cout; +using std::cerr; +using std::endl; + +namespace +{ + const unsigned col_width_package = 30; + const unsigned col_width_id = 40; + + void + write_repository_header(const RepositoryName & repo) + { + std::string s("Insecure packages from advisories in repository '" + stringify(repo) + "'"); + cout << std::string(s.length(), '=') << endl; + cout << s << endl; + cout << std::string(s.length(), '=') << endl; + cout << endl; + + cout << std::left + << std::setw(col_width_package) << "package" + << std::setw(col_width_id) << "GLSA IDs" + << endl; + + cout + << std::string(col_width_package - 1, '-') << " " + << std::string(col_width_id - 1, '-') << " " + << endl; + } + + class ListInsecureVisitor : + public DepAtomVisitorTypes::ConstVisitor + { + private: + const Environment & _env; + std::multimap<PackageDatabaseEntry, std::string> _found; + + public: + ListInsecureVisitor(const Environment & e) : + _env(e) + { + } + + void visit(const AllDepAtom * const a) + { + std::for_each(a->begin(), a->end(), accept_visitor(this)); + } + + void visit(const AnyDepAtom * const a) + { + std::for_each(a->begin(), a->end(), accept_visitor(this)); + } + + void visit(const UseDepAtom * const a) + { + std::for_each(a->begin(), a->end(), accept_visitor(this)); + } + + void visit(const PackageDepAtom * const a) + { + PackageDatabaseEntryCollection::ConstPointer insecure( + _env.package_database()->query(*a, is_either)); + for (PackageDatabaseEntryCollection::Iterator i(insecure->begin()), + i_end(insecure->end()) ; i != i_end ; ++i) + if (a->tag()) + _found.insert(std::make_pair(*i, a->tag()->short_text())); + else + throw InternalError(PALUDIS_HERE, "didn't get a tag"); + } + + void visit(const PlainTextDepAtom * const) + { + } + + void visit(const BlockDepAtom * const) + { + } + + friend std::ostream & operator<< (std::ostream &, const ListInsecureVisitor &); + }; + + std::ostream & operator<< (std::ostream & s, const ListInsecureVisitor & v) + { + QualifiedPackageName old_name("dormouse/teapot"); + for (std::multimap<PackageDatabaseEntry, std::string>::const_iterator + f(v._found.begin()), f_end(v._found.end()) ; f != f_end ; ++f) + { + if (f->first.name != old_name) + s << std::setw(col_width_package) << (stringify(f->first.name) + " ") << endl; + old_name = f->first.name; + s << std::setw(col_width_package) << (" " + stringify(f->first.version) + " ") + << f->second; + while (next(f) != f_end) + { + if (next(f)->first != f->first) + break; + cout << " " << f->second; + ++f; + } + cout << endl; + } + + return s; + } +} + +void do_find_insecure_packages(const Environment & env) +{ + Context context("When performing find-insecure-packages action:"); + + for (IndirectIterator<PackageDatabase::RepositoryIterator, const Repository> + r(env.package_database()->begin_repositories()), + r_end(env.package_database()->end_repositories()) ; r != r_end ; ++r) + { + if (r->name() == RepositoryName("virtuals")) + continue; + + if (! r->sets_interface) + continue; + + write_repository_header(r->name()); + + DepAtom::ConstPointer all_insecure(r->sets_interface->package_set("insecurity")); + if (! all_insecure) + continue; + ListInsecureVisitor v(env); + all_insecure->accept(&v); + cout << v << endl; + } +} + diff --git a/0.8.0/src/adjutrix/find_insecure_packages.hh b/0.8.0/src/adjutrix/find_insecure_packages.hh new file mode 100644 index 000000000..a8c1cc0e6 --- /dev/null +++ b/0.8.0/src/adjutrix/find_insecure_packages.hh @@ -0,0 +1,27 @@ +/* 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_SRC_ADJUTRIX_FIND_INSECURE_PACKAGES_HH +#define PALUDIS_GUARD_SRC_ADJUTRIX_FIND_INSECURE_PACKAGES_HH 1 + +#include <paludis/environment.hh> + +void do_find_insecure_packages(const paludis::Environment & env); + +#endif diff --git a/0.8.0/src/adjutrix/find_reverse_deps.cc b/0.8.0/src/adjutrix/find_reverse_deps.cc new file mode 100644 index 000000000..e61a09602 --- /dev/null +++ b/0.8.0/src/adjutrix/find_reverse_deps.cc @@ -0,0 +1,291 @@ +/* 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 "find_reverse_deps.hh" +#include "command_line.hh" +#include "colour.hh" + +#include <paludis/util/compare.hh> +#include <paludis/util/collection_concrete.hh> +#include <paludis/util/save.hh> + +#include <set> +#include <map> +#include <iostream> +#include <iomanip> +#include <algorithm> + +using namespace paludis; +using std::cout; +using std::cerr; +using std::endl; + +namespace +{ + class ReverseDepChecker : + public DepAtomVisitorTypes::ConstVisitor + { + private: + PackageDatabase::ConstPointer _db; + PackageDatabaseEntryCollection::ConstPointer _entries; + std::string _depname; + std::string _p; + + bool _in_any; + bool _in_use; + std::string _flags; + + bool _found_matches; + + public: + ReverseDepChecker(PackageDatabase::ConstPointer db, PackageDatabaseEntryCollection::ConstPointer entries, + const std::string & p) : + _db(db), + _entries(entries), + _depname(""), + _p(p), + _in_any(false), + _in_use(false), + _found_matches(false) + { + } + + void check(DepAtom::ConstPointer atom, const std::string & depname) + { + _depname = depname; + atom->accept(this); + } + + bool found_matches() + { + return _found_matches; + } + + void visit(const AllDepAtom * const); + + void visit(const AnyDepAtom * const); + + void visit(const UseDepAtom * const); + + void visit(const PackageDepAtom * const); + + void visit(const PlainTextDepAtom * const); + + void visit(const BlockDepAtom * const); + }; + + void + ReverseDepChecker::visit(const AllDepAtom * const a) + { + std::for_each(a->begin(), a->end(), accept_visitor(this)); + } + + void + ReverseDepChecker::visit(const AnyDepAtom * const a) + { + Save<bool> in_any_save(&_in_any, true); + + std::for_each(a->begin(), a->end(), accept_visitor(this)); + } + + void + ReverseDepChecker::visit(const UseDepAtom * const a) + { + Save<bool> in_use_save(&_in_use, true); + Save<std::string> flag_save(&_flags); + + if (! _flags.empty()) + _flags += " "; + _flags += (a->inverse() ? "!" : "") + stringify(a->flag()); + + std::for_each(a->begin(), a->end(), accept_visitor(this)); + } + + void + ReverseDepChecker::visit(const PackageDepAtom * const a) + { + PackageDatabaseEntryCollection::ConstPointer dep_entries( + _db->query(*a, is_uninstalled_only)); + PackageDatabaseEntryCollection::Pointer matches(new PackageDatabaseEntryCollection::Concrete); + + bool header_written = false; + + for (PackageDatabaseEntryCollection::Iterator e(dep_entries->begin()), e_end(dep_entries->end()) ; + e != e_end ; ++e) + { + if (_entries->find(*e) != _entries->end()) + { + _found_matches |= true; + + if (! header_written) + { + std::cout << " " << _p << " " + _depname + " on one of:" << std::endl; + header_written = true; + } + std::cout << " " << stringify(*e); + + if (_in_use || _in_any) + { + std::cout << " ("; + + if (_in_any) + std::cout << "any-of"; + + if (_in_use && _in_any) + std::cout << ", "; + + if (_in_use) + std::cout << "condition USE='" << _flags << "'"; + + std::cout << ")"; + } + std::cout << std::endl; + } + } + } + + void + ReverseDepChecker::visit(const PlainTextDepAtom * const) + { + } + + void + ReverseDepChecker::visit(const BlockDepAtom * const) + { + } + + void write_repository_header(std::string atom, const std::string &) + { + cout << "Reverse dependencies for '" << atom << "':" << std::endl; + } + + int check_one_package(const Environment & env, const Repository & r, + const PackageDatabaseEntryCollection & entries, const QualifiedPackageName & p) + { + Context context("When checking package '" + stringify(p) + "':"); + + PackageDatabaseEntryCollection::Pointer p_entries(env.package_database()->query( + PackageDepAtom::Pointer(new PackageDepAtom(stringify(p))), is_uninstalled_only)); + + bool found_matches(false); + + for (PackageDatabaseEntryCollection::Iterator e(p_entries->begin()), e_end(p_entries->end()) ; + e != e_end ; ++e) + { + try + { + VersionMetadata::ConstPointer metadata(r.version_metadata(e->name, e->version)); + ReverseDepChecker checker(env.package_database(), PackageDatabaseEntryCollection::ConstPointer(&entries), + stringify(p) + "-" + stringify(e->version)); + + checker.check(metadata->deps.parser(metadata->deps.build_depend_string), std::string("DEPEND")); + checker.check(metadata->deps.parser(metadata->deps.run_depend_string), std::string("RDEPEND")); + checker.check(metadata->deps.parser(metadata->deps.post_depend_string), std::string("PDEPEND")); + + found_matches |= checker.found_matches(); + } + catch (Exception & exception) + { + cerr << "Caught exception:" << endl; + cerr << " * " << exception.backtrace("\n * ") << endl; + cerr << " * " << exception.message() << " (" << exception.what() << ")" << endl; + return (found_matches ? 0 : 1) | 2; + } + } + + return found_matches ? 0 : 1; + } +} + +int do_find_reverse_deps(NoConfigEnvironment & env) +{ + Context context("When performing find-reverse-deps action:"); + + PackageDepAtom::Pointer atom(0); + try + { + if (std::string::npos == CommandLine::get_instance()->begin_parameters()->find('/')) + { + atom.assign(new PackageDepAtom(env.package_database()->fetch_unique_qualified_package_name( + PackageNamePart(*CommandLine::get_instance()->begin_parameters())))); + } + else + atom.assign(new PackageDepAtom(*CommandLine::get_instance()->begin_parameters())); + } + 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 4; + } + + PackageDatabaseEntryCollection::Pointer entries(env.package_database()->query(atom, is_either)); + int ret(0); + + if (entries->empty()) + return 1; + + for (IndirectIterator<PackageDatabase::RepositoryIterator, const Repository> + r(env.package_database()->begin_repositories()), + r_end(env.package_database()->end_repositories()) ; r != r_end ; ++r) + { + if (r->name() == RepositoryName("virtuals")) + continue; + + write_repository_header(stringify(*atom), stringify(r->name())); + + CategoryNamePartCollection::ConstPointer cat_names(r->category_names()); + for (CategoryNamePartCollection::Iterator c(cat_names->begin()), c_end(cat_names->end()) ; + c != c_end ; ++c) + { + cerr << xterm_title("Checking " + stringify(*c) + " - adjutrix"); + + if (CommandLine::get_instance()->a_category.specified()) + if (CommandLine::get_instance()->a_category.args_end() == std::find( + CommandLine::get_instance()->a_category.args_begin(), + CommandLine::get_instance()->a_category.args_end(), + stringify(*c))) + continue; + + QualifiedPackageNameCollection::ConstPointer pkg_names(r->package_names(*c)); + for (QualifiedPackageNameCollection::Iterator p(pkg_names->begin()), p_end(pkg_names->end()) ; + p != p_end ; ++p) + { + if (CommandLine::get_instance()->a_package.specified()) + if (CommandLine::get_instance()->a_package.args_end() == std::find( + CommandLine::get_instance()->a_package.args_begin(), + CommandLine::get_instance()->a_package.args_end(), + stringify(p->package))) + continue; + + ret |= check_one_package(env, *r, *entries, *p); + } + } + } + + return ret; +} + + diff --git a/0.8.0/src/adjutrix/find_reverse_deps.hh b/0.8.0/src/adjutrix/find_reverse_deps.hh new file mode 100644 index 000000000..048b1f5bc --- /dev/null +++ b/0.8.0/src/adjutrix/find_reverse_deps.hh @@ -0,0 +1,28 @@ +/* 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_ARCHTOOL_FIND_REVERSE_DEPS_HH +#define PALUDIS_GUARD_SRC_ARCHTOOL_FIND_REVERSE_DEPS_HH 1 + +#include <paludis/environment/no_config/no_config_environment.hh> + +int do_find_reverse_deps(paludis::NoConfigEnvironment & env); + +#endif + diff --git a/0.8.0/src/adjutrix/find_stable_candidates.cc b/0.8.0/src/adjutrix/find_stable_candidates.cc new file mode 100644 index 000000000..9d26c7d46 --- /dev/null +++ b/0.8.0/src/adjutrix/find_stable_candidates.cc @@ -0,0 +1,210 @@ +/* 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 "find_stable_candidates.hh" +#include "command_line.hh" + +#include <paludis/util/tokeniser.hh> +#include <paludis/util/compare.hh> + +#include <set> +#include <map> +#include <iostream> +#include <iomanip> +#include <algorithm> + +using namespace paludis; +using std::cout; +using std::cerr; +using std::endl; + +namespace +{ + +#include "find_stable_candidates-sr.hh" +#include "find_stable_candidates-sr.cc" + + static const int col_width_package = 30; + static const int col_width_our_version = 20; + static const int col_width_best_version = 20; + + void + write_repository_header(const KeywordName & keyword, const RepositoryName & repo) + { + std::string s("Stable candidates for '" + stringify(repo) + "' on '" + + stringify(keyword) + "'"); + cout << std::string(s.length(), '=') << endl; + cout << s << endl; + cout << std::string(s.length(), '=') << endl; + cout << endl; + + cout << std::left + << std::setw(col_width_package) << "category/package (:slot)" + << std::setw(col_width_our_version) << "our version" + << std::setw(col_width_best_version) << "best version" + << endl; + + cout + << std::string(col_width_package - 1, '-') << " " + << std::string(col_width_our_version - 1, '-') << " " + << std::string(col_width_best_version - 1, '-') << " " + << endl; + } + + struct IsStableKeyword + { + bool operator() (const KeywordName & k) const + { + return std::string::npos == std::string("-~").find(k.data().at(0)); + } + }; + + void + write_package(const QualifiedPackageName & package, const SlotName & slot, + const VersionSpec & our_version, const VersionSpec & best_version) + { + static CategoryNamePart previous_category("not-on-a-boat"); + if (package.category != previous_category) + { + cout << std::setw(col_width_package) << (stringify(package.category) + "/") << endl; + previous_category = package.category; + } + + std::string p(stringify(package.package)); + if (SlotName("0") != slot) + p += ":" + stringify(slot); + cout << " " << std::setw(col_width_package - 2) << p; + + if (our_version != VersionSpec("0")) + cout << std::setw(col_width_our_version) << our_version; + else + cout << std::setw(col_width_our_version) << " "; + cout << std::setw(col_width_best_version) << best_version; + cout << endl; + } + + void + check_one_package(const Environment &, const KeywordName & keyword, + const Repository & repo, const QualifiedPackageName & package) + { + /* determine whether we have any interesting versions, and pick out + * slots where we do. for slots, we map slot to a pair (best stable + * version for us, best stable version for anyone). */ + + bool is_interesting(false); + typedef std::map<SlotName, SlotsEntry> SlotsToVersions; + SlotsToVersions slots_to_versions; + + VersionSpecCollection::ConstPointer versions(repo.version_specs(package)); + for (VersionSpecCollection::Iterator v(versions->begin()), v_end(versions->end()) ; + v != v_end ; ++v) + { + VersionMetadata::ConstPointer metadata(repo.version_metadata(package, *v)); + if (! metadata->get_ebuild_interface()) + continue; + + std::set<KeywordName> keywords; + WhitespaceTokeniser::get_instance()->tokenise(metadata->get_ebuild_interface()->keywords, + create_inserter<KeywordName>(std::inserter(keywords, keywords.end()))); + + if (keywords.end() != keywords.find(keyword)) + { + is_interesting = true; + + /* replace the entry */ + slots_to_versions.erase(metadata->slot); + slots_to_versions.insert(std::make_pair(metadata->slot, + SlotsEntry(SlotsEntry::create() + .our_version(*v) + .best_version(VersionSpec("0"))))); + } + + if (keywords.end() != std::find_if(keywords.begin(), keywords.end(), IsStableKeyword())) + { + /* ensure that an entry exists */ + slots_to_versions.insert(std::make_pair(metadata->slot, + SlotsEntry(SlotsEntry::create() + .our_version(VersionSpec("0")) + .best_version(*v)))); + + /* update the entry to mark our current version as the best + * version */ + if (slots_to_versions.find(metadata->slot)->second.best_version <= *v) + slots_to_versions.find(metadata->slot)->second.best_version = *v; + } + } + + if (! is_interesting) + return; + + /* for each slot, if there's a higher stable version on another arch, flag it */ + for (SlotsToVersions::const_iterator s(slots_to_versions.begin()), + s_end(slots_to_versions.end()) ; s != s_end ; ++s) + { + if (s->second.our_version >= s->second.best_version) + continue; + + write_package(package, s->first, s->second.our_version, s->second.best_version); + } + } +} + +void do_find_stable_candidates(const Environment & env) +{ + Context context("When performing find-stable-candidates action:"); + + KeywordName keyword(*CommandLine::get_instance()->begin_parameters()); + + for (IndirectIterator<PackageDatabase::RepositoryIterator, const Repository> + r(env.package_database()->begin_repositories()), + r_end(env.package_database()->end_repositories()) ; r != r_end ; ++r) + { + if (r->name() == RepositoryName("virtuals")) + continue; + + write_repository_header(keyword, r->name()); + + CategoryNamePartCollection::ConstPointer cat_names(r->category_names()); + for (CategoryNamePartCollection::Iterator c(cat_names->begin()), c_end(cat_names->end()) ; + c != c_end ; ++c) + { + if (CommandLine::get_instance()->a_category.specified()) + if (CommandLine::get_instance()->a_category.args_end() == std::find( + CommandLine::get_instance()->a_category.args_begin(), + CommandLine::get_instance()->a_category.args_end(), + stringify(*c))) + continue; + + QualifiedPackageNameCollection::ConstPointer pkg_names(r->package_names(*c)); + for (QualifiedPackageNameCollection::Iterator p(pkg_names->begin()), p_end(pkg_names->end()) ; + p != p_end ; ++p) + { + if (CommandLine::get_instance()->a_package.specified()) + if (CommandLine::get_instance()->a_package.args_end() == std::find( + CommandLine::get_instance()->a_package.args_begin(), + CommandLine::get_instance()->a_package.args_end(), + stringify(p->package))) + continue; + + check_one_package(env, keyword, *r, *p); + } + } + } +} + diff --git a/0.8.0/src/adjutrix/find_stable_candidates.hh b/0.8.0/src/adjutrix/find_stable_candidates.hh new file mode 100644 index 000000000..286097568 --- /dev/null +++ b/0.8.0/src/adjutrix/find_stable_candidates.hh @@ -0,0 +1,27 @@ +/* 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_SRC_ARCHTOOL_FIND_STABLE_CANDIDATES_HH +#define PALUDIS_GUARD_SRC_ARCHTOOL_FIND_STABLE_CANDIDATES_HH 1 + +#include <paludis/environment.hh> + +void do_find_stable_candidates(const paludis::Environment & env); + +#endif diff --git a/0.8.0/src/adjutrix/find_stable_candidates.sr b/0.8.0/src/adjutrix/find_stable_candidates.sr new file mode 100644 index 000000000..9172a89d1 --- /dev/null +++ b/0.8.0/src/adjutrix/find_stable_candidates.sr @@ -0,0 +1,12 @@ +#!/bin/bash +# vim: set sw=4 sts=4 et : + +make_class_SlotsEntry() +{ + key our_version VersionSpec + key best_version VersionSpec + + allow_named_args +} + + diff --git a/0.8.0/src/adjutrix/find_stable_candidates_TEST b/0.8.0/src/adjutrix/find_stable_candidates_TEST new file mode 100755 index 000000000..9ae9850ff --- /dev/null +++ b/0.8.0/src/adjutrix/find_stable_candidates_TEST @@ -0,0 +1,18 @@ +#!/bin/bash + +./adjutrix --find-stable-candidates -D find_stable_candidates_TEST_dir/ best | \ + tee find_stable_candidates_TEST_dir/out1.txt + +if grep --silent '^ ' find_stable_candidates_TEST_dir/out1.txt ; then + echo "out1 failed" 1>&2 + exit 127 +fi + +./adjutrix --find-stable-candidates -D find_stable_candidates_TEST_dir/ one | \ + tee find_stable_candidates_TEST_dir/out2.txt + +if [[ $(grep --count '^ ' find_stable_candidates_TEST_dir/out2.txt ) != "1" ]] ; then + echo "out2 failed" 1>&2 + exit 127 +fi + diff --git a/0.8.0/src/adjutrix/find_stable_candidates_TEST_cleanup.sh b/0.8.0/src/adjutrix/find_stable_candidates_TEST_cleanup.sh new file mode 100755 index 000000000..1bdc7c11a --- /dev/null +++ b/0.8.0/src/adjutrix/find_stable_candidates_TEST_cleanup.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# vim: set ft=sh sw=4 sts=4 et : + +if [ -d find_stable_candidates_TEST_dir ] ; then + rm -fr find_stable_candidates_TEST_dir +else + true +fi + + + diff --git a/0.8.0/src/adjutrix/find_stable_candidates_TEST_setup.sh b/0.8.0/src/adjutrix/find_stable_candidates_TEST_setup.sh new file mode 100755 index 000000000..74a0a4ab4 --- /dev/null +++ b/0.8.0/src/adjutrix/find_stable_candidates_TEST_setup.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# vim: set ft=sh sw=4 sts=4 et : + +mkdir find_stable_candidates_TEST_dir || exit 1 +cd find_stable_candidates_TEST_dir || exit 1 + +mkdir -p {eclass,distfiles,profiles/profile} || exit 1 +echo "test-repo-1" > profiles/repo_name || exit 1 +cat <<END > profiles/categories || exit 1 +cat-one +cat-two +cat-three +END +cat <<END > profiles/profile/make.defaults +ARCH=test +END + +mkdir cat-one +mkdir cat-one/pkg-one +cat <<"END" > cat-one/pkg-one/pkg-one-1.ebuild +DESCRIPTION="one" +SLOT="0" +KEYWORDS="best one" +END + +cat <<"END" > cat-one/pkg-one/pkg-one-2.ebuild +DESCRIPTION="one" +SLOT="0" +KEYWORDS="best" +END + +mkdir cat-one/pkg-two +cat <<"END" > cat-one/pkg-two/pkg-two-1.ebuild +DESCRIPTION="one" +SLOT="0" +KEYWORDS="foo" +END + +cat <<"END" > cat-one/pkg-one/pkg-two-2.ebuild +DESCRIPTION="one" +SLOT="0" +KEYWORDS="bar" +END + +mkdir cat-one/pkg-three +cat <<"END" > cat-one/pkg-two/pkg-three-1.ebuild +DESCRIPTION="one" +SLOT="0" +KEYWORDS="best one" +END + +cat <<"END" > cat-one/pkg-one/pkg-three-2.ebuild +DESCRIPTION="one" +SLOT="0" +KEYWORDS="best one" +END + +mkdir cat-one/pkg-four +cat <<"END" > cat-one/pkg-two/pkg-four-1.ebuild +DESCRIPTION="one" +SLOT="0" +KEYWORDS="best one" +END + +cat <<"END" > cat-one/pkg-one/pkg-four-2.ebuild +DESCRIPTION="one" +SLOT="0" +KEYWORDS="~best ~one" +END + + diff --git a/0.8.0/src/adjutrix/help_TEST b/0.8.0/src/adjutrix/help_TEST new file mode 100755 index 000000000..7694394b9 --- /dev/null +++ b/0.8.0/src/adjutrix/help_TEST @@ -0,0 +1,4 @@ +#!/bin/bash + +./adjutrix --help + diff --git a/0.8.0/src/adjutrix/keywords_graph.cc b/0.8.0/src/adjutrix/keywords_graph.cc new file mode 100644 index 000000000..f4fef801e --- /dev/null +++ b/0.8.0/src/adjutrix/keywords_graph.cc @@ -0,0 +1,195 @@ +/* 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 "keywords_graph.hh" +#include "command_line.hh" +#include "colour.hh" + +#include <paludis/util/tokeniser.hh> +#include <paludis/util/compare.hh> + +#include <set> +#include <map> +#include <iostream> +#include <iomanip> +#include <algorithm> + +using namespace paludis; +using std::cout; +using std::cerr; +using std::endl; + +using namespace paludis; + +namespace +{ + struct CompareByStringLength + { + template<typename T_> + bool + operator() (const T_ & l, const T_ & r) const + { + return stringify(l).length() < stringify(r).length(); + } + }; + + void + write_keywords_graph(const Environment &, const Repository & repo, + const QualifiedPackageName & package) + { + Context context("When writing keyword graph for '" + stringify(package) + "' in '" + + stringify(repo.name()) + "':"); + + cout << "Keywords for " << package << ":" << endl; + cout << endl; + + VersionSpecCollection::ConstPointer versions(repo.version_specs(package)); + if (versions->empty()) + return; + + if (! repo.use_interface) + throw InternalError(PALUDIS_HERE, "Repository has no use_interface"); + + UseFlagNameCollection::ConstPointer arch_flags(repo.use_interface->arch_flags()); + if (arch_flags->empty()) + return; + + std::set<SlotName> slots; + for (VersionSpecCollection::Iterator v(versions->begin()), v_end(versions->end()) ; + v != v_end ; ++v) + slots.insert(repo.version_metadata(package, *v)->slot); + + unsigned version_specs_columns_width(stringify(*std::max_element(versions->begin(), + versions->end(), CompareByStringLength())).length() + 1); + + unsigned tallest_arch_name(std::max(stringify(*std::max_element(arch_flags->begin(), + arch_flags->end(), CompareByStringLength())).length(), static_cast<std::size_t>(4))); + + unsigned longest_slot_name(stringify(*std::max_element(slots.begin(), + slots.end(), CompareByStringLength())).length()); + + for (unsigned h = 0 ; h < tallest_arch_name ; ++h) + { + cout << std::left << std::setw(version_specs_columns_width) << " " << "| "; + for (UseFlagNameCollection::Iterator a(arch_flags->begin()), a_end(arch_flags->end()) ; + a != a_end ; ++a) + { + if ((tallest_arch_name - h) > a->data().length()) + cout << " "; + else + cout << a->data().at(a->data().length() - tallest_arch_name + h) << " "; + } + cout << "| "; + if ((tallest_arch_name - h) <= 4) + cout << std::string("slot").at(4 - tallest_arch_name + h); + cout << endl; + } + + cout << std::string(version_specs_columns_width, '-') << "+" + << std::string(arch_flags->size() * 2 + 1, '-') << "+" + << std::string(longest_slot_name + 1, '-') << endl; + + SlotName old_slot("first_slot"); + for (VersionSpecCollection::Iterator v(versions->begin()), v_end(versions->end()) ; + v != v_end ; ++v) + { + VersionMetadata::ConstPointer metadata(repo.version_metadata(package, *v)); + if (! metadata->get_ebuild_interface()) + continue; + + if (metadata->slot != old_slot) + if (old_slot != SlotName("first_slot")) + cout << std::string(version_specs_columns_width, '-') << "+" + << std::string(arch_flags->size() * 2 + 1, '-') << "+" + << std::string(longest_slot_name + 1, '-') << endl; + + cout << std::left << std::setw(version_specs_columns_width) << *v << "| "; + + std::set<KeywordName> keywords; + WhitespaceTokeniser::get_instance()->tokenise(metadata->get_ebuild_interface()->keywords, + create_inserter<KeywordName>(std::inserter(keywords, keywords.end()))); + + for (UseFlagNameCollection::Iterator a(arch_flags->begin()), a_end(arch_flags->end()) ; + a != a_end ; ++a) + { + if (keywords.end() != keywords.find(KeywordName(stringify(*a)))) + cout << colour(cl_bold_green, "+ "); + else if (keywords.end() != keywords.find(KeywordName("~" + stringify(*a)))) + cout << colour(cl_bold_yellow, "~ "); + else if (keywords.end() != keywords.find(KeywordName("-" + stringify(*a)))) + cout << colour(cl_red, "- "); + else if (keywords.end() != keywords.find(KeywordName("-*"))) + cout << colour(cl_red, "* "); + else + cout << " "; + } + + cout << "| "; + if (metadata->slot != old_slot) + { + cout << metadata->slot; + old_slot = metadata->slot; + } + + cout << endl; + } + + cout << endl; + } +} + +void do_keywords_graph(const Environment & env) +{ + Context context("When performing keywords-graph action:"); + + for (IndirectIterator<PackageDatabase::RepositoryIterator, const Repository> + r(env.package_database()->begin_repositories()), + r_end(env.package_database()->end_repositories()) ; r != r_end ; ++r) + { + if (r->name() == RepositoryName("virtuals")) + continue; + + CategoryNamePartCollection::ConstPointer cat_names(r->category_names()); + for (CategoryNamePartCollection::Iterator c(cat_names->begin()), c_end(cat_names->end()) ; + c != c_end ; ++c) + { + if (CommandLine::get_instance()->a_category.specified()) + if (CommandLine::get_instance()->a_category.args_end() == std::find( + CommandLine::get_instance()->a_category.args_begin(), + CommandLine::get_instance()->a_category.args_end(), + stringify(*c))) + continue; + + QualifiedPackageNameCollection::ConstPointer pkg_names(r->package_names(*c)); + for (QualifiedPackageNameCollection::Iterator p(pkg_names->begin()), p_end(pkg_names->end()) ; + p != p_end ; ++p) + { + if (CommandLine::get_instance()->a_package.specified()) + if (CommandLine::get_instance()->a_package.args_end() == std::find( + CommandLine::get_instance()->a_package.args_begin(), + CommandLine::get_instance()->a_package.args_end(), + stringify(p->package))) + continue; + + write_keywords_graph(env, *r, *p); + } + } + } +} + diff --git a/0.8.0/src/adjutrix/keywords_graph.hh b/0.8.0/src/adjutrix/keywords_graph.hh new file mode 100644 index 000000000..7376143a4 --- /dev/null +++ b/0.8.0/src/adjutrix/keywords_graph.hh @@ -0,0 +1,27 @@ +/* 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_SRC_ARCHTOOL_KEYWORDS_GRAPH_HH +#define PALUDIS_GUARD_SRC_ARCHTOOL_KEYWORDS_GRAPH_HH 1 + +#include <paludis/environment.hh> + +void do_keywords_graph(const paludis::Environment & env); + +#endif diff --git a/0.8.0/src/adjutrix/man_adjutrix.cc b/0.8.0/src/adjutrix/man_adjutrix.cc new file mode 100644 index 000000000..d36aa1dcd --- /dev/null +++ b/0.8.0/src/adjutrix/man_adjutrix.cc @@ -0,0 +1,36 @@ +/* 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 "command_line.hh" +#include <paludis/args/man.hh> + +#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/0.8.0/src/adjutrix/version_TEST b/0.8.0/src/adjutrix/version_TEST new file mode 100755 index 000000000..7d5c45e16 --- /dev/null +++ b/0.8.0/src/adjutrix/version_TEST @@ -0,0 +1,3 @@ +#!/bin/bash + +./adjutrix --version diff --git a/0.8.0/src/colour.cc b/0.8.0/src/colour.cc new file mode 100644 index 000000000..d971d7e38 --- /dev/null +++ b/0.8.0/src/colour.cc @@ -0,0 +1,59 @@ +/* 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 "colour.hh" +#include <paludis/util/system.hh> +#include <unistd.h> + +namespace +{ + static bool can_use_colour = true; +} + +bool +use_colour() +{ + if (! can_use_colour) + return false; + + static bool result( + (1 == isatty(1)) && + (0 != paludis::getenv_with_default("TERM", "").compare(0, 4, "dumb"))); + + return result; +} + +void +set_use_colour(const bool value) +{ + can_use_colour = value; +} + +bool +use_xterm_titles() +{ + static bool result( + (0 != paludis::getenv_with_default("TERM", "").compare(0, 4, "dumb")) && + (0 != paludis::getenv_with_default("TERM", "").compare(0, 5, "linux")) && + (0 == paludis::getenv_with_default("PALUDIS_NO_XTERM_TITLES", "").length())); + + return result; +} + + diff --git a/0.8.0/src/colour.hh b/0.8.0/src/colour.hh new file mode 100644 index 000000000..1e42b0bf2 --- /dev/null +++ b/0.8.0/src/colour.hh @@ -0,0 +1,106 @@ +/* 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_SRC_COLOUR_HH +#define PALUDIS_GUARD_SRC_COLOUR_HH 1 + +#include <paludis/util/stringify.hh> +#include <config.h> +#include <string> + +enum Colour +{ + cl_none = 0, + cl_red = 31, + cl_green = 32, + cl_yellow = 33, + cl_blue = 34, + cl_pink = 35, + cl_grey = 38, + + cl_bold_red = cl_red + 100, + cl_bold_green = cl_green + 100, + cl_bold_yellow = cl_yellow + 100, + cl_bold_blue = cl_blue + 100, + cl_bold_pink = cl_pink + 100, + +#if PALUDIS_COLOUR_PINK==1 + cl_package_name = cl_bold_pink, + cl_repository_name = cl_pink, + cl_flag_on = cl_pink, + cl_flag_off = cl_red, + cl_slot = cl_blue, + cl_visible = cl_flag_on, + cl_masked = cl_flag_off, + cl_not_masked = cl_flag_on, + cl_heading = cl_bold_pink, + cl_updatemode = cl_yellow, + cl_tag = cl_yellow, + cl_key_name = cl_pink, +#else + cl_package_name = cl_bold_blue, + cl_repository_name = cl_blue, + cl_flag_on = cl_green, + cl_flag_off = cl_red, + cl_slot = cl_blue, + cl_visible = cl_flag_on, + cl_masked = cl_flag_off, + cl_not_masked = cl_flag_on, + cl_heading = cl_bold_green, + cl_updatemode = cl_yellow, + cl_tag = cl_yellow, + cl_key_name = cl_blue, +#endif + + cl_unimportant = cl_grey, + cl_error = cl_bold_red, + + cl_file = cl_none, + cl_dir = cl_blue, + cl_sym = cl_pink, + cl_misc = cl_red +}; + +bool use_colour(); +void set_use_colour(const bool value); +bool use_xterm_titles() PALUDIS_ATTRIBUTE((pure)); + +template <typename T_> +std::string colour(Colour colour, const T_ & s) +{ + if (! use_colour()) + return paludis::stringify(s); + else if (cl_none != colour) + return "\033[" + paludis::stringify(static_cast<unsigned>(colour) / 100) + ";" + + paludis::stringify(static_cast<unsigned>(colour) % 100) + "m" + paludis::stringify(s) + + "\033[0;0m"; + else + return paludis::stringify(s); +} + +template <typename T_> +std::string xterm_title(const T_ & s) +{ + if (! use_colour() || ! use_xterm_titles()) + return ""; + else + return "\x1b]2;" + paludis::stringify(s) + "\x07"; +} + +#endif diff --git a/0.8.0/src/gtkpaludis/Makefile.am b/0.8.0/src/gtkpaludis/Makefile.am new file mode 100644 index 000000000..e64e95690 --- /dev/null +++ b/0.8.0/src/gtkpaludis/Makefile.am @@ -0,0 +1,44 @@ +AM_CXXFLAGS = -I$(top_srcdir) \ + @PALUDIS_CXXFLAGS@ \ + @PALUDIS_CXXFLAGS_NO_WOLD_STYLE_CAST@ \ + @PALUDIS_CXXFLAGS_NO_WREDUNDANT_DECLS@ \ + @PALUDIS_CXXFLAGS_NO_WSHADOW@ + +DEFS = \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DGLIBMM_EXCEPTIONS_ENABLED=1 + +SUBDIRS = vtemm . + +INCLUDES = $(GTKDEPS_CFLAGS) + +if ENABLE_GTK + +bin_PROGRAMS = gtkpaludis + +gtkpaludis_SOURCES = \ + command_line.cc command_line.hh \ + browse_tree.cc browse_tree.hh \ + information_tree.cc information_tree.hh \ + vte_message_window.hh vte_message_window.cc \ + main_window.cc main_window.hh \ + sync.cc sync.hh \ + gtkpaludis.cc + +gtkpaludis_LDADD = \ + $(top_builddir)/src/gtkpaludis/vtemm/libvtemm.a \ + $(top_builddir)/paludis/tasks/libpaludistasks.a \ + $(top_builddir)/paludis/libpaludis.la \ + $(top_builddir)/paludis/args/libpaludisargs.la \ + $(top_builddir)/paludis/util/libpaludisutil.la \ + $(top_builddir)/paludis/environment/default/libpaludisdefaultenvironment.la \ + $(GTKDEPS_LIBS) \ + $(DYNAMIC_LD_LIBS) + +endif + +CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda +MAINTAINERCLEANFILES = Makefile.in + + diff --git a/0.8.0/src/gtkpaludis/browse_tree.cc b/0.8.0/src/gtkpaludis/browse_tree.cc new file mode 100644 index 000000000..fda7a3ce8 --- /dev/null +++ b/0.8.0/src/gtkpaludis/browse_tree.cc @@ -0,0 +1,450 @@ +/* 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 "browse_tree.hh" +#include "information_tree.hh" +#include "main_window.hh" +#include "sync.hh" +#include "vtemm/reaper.hh" + +#include <gtkmm/treestore.h> +#include <gtkmm/menu.h> +#include <gtkmm/messagedialog.h> + +#include <paludis/environment/default/default_environment.hh> +#include <paludis/util/log.hh> +#include <paludis/syncer.hh> + +#include <sys/types.h> +#include <sys/wait.h> +#include <iostream> + +using namespace paludis; + +namespace +{ + class BrowseTreeColumns; + + class BrowseTreeDisplayData : + public InternalCounted<BrowseTreeDisplayData> + { + private: + bool _has_children; + + protected: + BrowseTreeDisplayData(); + + virtual void load_children( + Glib::RefPtr<Gtk::TreeStore>, + const BrowseTreeColumns & columns, + Gtk::TreeModel::iterator) const = 0; + + public: + virtual ~BrowseTreeDisplayData(); + + virtual void display(InformationTree * const information_tree) const = 0; + + virtual void sync() const + { + } + + virtual void need_children( + Glib::RefPtr<Gtk::TreeStore> model, + const BrowseTreeColumns & columns, + Gtk::TreeModel::iterator us) + { + if (! _has_children) + { + load_children(model, columns, us); + _has_children = true; + } + } + + class DefaultablePointer : + public Pointer + { + public: + DefaultablePointer() : + Pointer(0) + { + } + + template <typename T_> + DefaultablePointer(T_ v) : + Pointer(v) + { + } + }; + }; + + class BrowseTreeColumns : + public Gtk::TreeModel::ColumnRecord + { + public: + BrowseTreeColumns(); + ~BrowseTreeColumns(); + + Gtk::TreeModelColumn<Glib::ustring> col_item; + Gtk::TreeModelColumn<BrowseTreeDisplayData::DefaultablePointer> col_data; + }; + + class BrowseTreeDisplayTopData : + public BrowseTreeDisplayData + { + protected: + virtual void load_children( + Glib::RefPtr<Gtk::TreeStore>, + const BrowseTreeColumns &, + Gtk::TreeModel::iterator) const + { + } + + public: + virtual void display(InformationTree * const information_tree) const + { + information_tree->show_top(); + } + }; + + class BrowseTreeDisplayVersionData : + public BrowseTreeDisplayData + { + private: + RepositoryName _r; + QualifiedPackageName _q; + VersionSpec _v; + + protected: + virtual void load_children( + Glib::RefPtr<Gtk::TreeStore>, + const BrowseTreeColumns &, + Gtk::TreeModel::iterator) const + { + } + + public: + BrowseTreeDisplayVersionData(const RepositoryName & r, + const QualifiedPackageName q, const VersionSpec & v) : + _r(r), + _q(q), + _v(v) + { + } + + virtual void display(InformationTree * const information_tree) const + { + information_tree->show_version(_r, _q, _v); + } + }; + + class BrowseTreeDisplayPackageData : + public BrowseTreeDisplayData + { + private: + RepositoryName _r; + QualifiedPackageName _q; + + protected: + virtual void load_children( + Glib::RefPtr<Gtk::TreeStore> model, + const BrowseTreeColumns & columns, + Gtk::TreeModel::iterator us) const + { + Repository::ConstPointer repo( + DefaultEnvironment::get_instance()->package_database()->fetch_repository(_r)); + + VersionSpecCollection::ConstPointer vers(repo->version_specs(_q)); + for (VersionSpecCollection::Iterator ver(vers->begin()), ver_end(vers->end()) ; + ver != ver_end ; ++ver) + { + Gtk::TreeModel::Row ver_row = *(model->append(us->children())); + ver_row[columns.col_item] = stringify(*ver); + ver_row[columns.col_data] = BrowseTreeDisplayData::Pointer( + new BrowseTreeDisplayVersionData(_r, _q, *ver)); + } + } + + public: + BrowseTreeDisplayPackageData(const RepositoryName & r, + const QualifiedPackageName q) : + _r(r), + _q(q) + { + } + + virtual void display(InformationTree * const information_tree) const + { + information_tree->show_package(_r, _q); + } + }; + + class BrowseTreeDisplayCategoryData : + public BrowseTreeDisplayData + { + private: + RepositoryName _r; + CategoryNamePart _c; + + protected: + virtual void load_children( + Glib::RefPtr<Gtk::TreeStore> model, + const BrowseTreeColumns & columns, + Gtk::TreeModel::iterator us) const + { + Repository::ConstPointer repo( + DefaultEnvironment::get_instance()->package_database()->fetch_repository(_r)); + + QualifiedPackageNameCollection::ConstPointer pkgs(repo->package_names(_c)); + for (QualifiedPackageNameCollection::Iterator pkg(pkgs->begin()), pkg_end(pkgs->end()) ; + pkg != pkg_end ; ++pkg) + { + Gtk::TreeModel::Row pkg_row = *(model->append(us->children())); + pkg_row[columns.col_item] = stringify(pkg->package); + pkg_row[columns.col_data] = BrowseTreeDisplayData::Pointer( + new BrowseTreeDisplayPackageData(_r, *pkg)); + } + } + + public: + BrowseTreeDisplayCategoryData(const RepositoryName & r, + const CategoryNamePart c) : + _r(r), + _c(c) + { + } + + virtual void display(InformationTree * const information_tree) const + { + information_tree->show_category(_r, _c); + } + }; + + class BrowseTreeDisplayRepositoryData : + public BrowseTreeDisplayData + { + private: + RepositoryName _r; + + protected: + virtual void load_children( + Glib::RefPtr<Gtk::TreeStore> model, + const BrowseTreeColumns & columns, + Gtk::TreeModel::iterator us) const + { + Repository::ConstPointer repo( + DefaultEnvironment::get_instance()->package_database()->fetch_repository(_r)); + + CategoryNamePartCollection::ConstPointer cats(repo->category_names()); + for (CategoryNamePartCollection::Iterator cat(cats->begin()), cat_end(cats->end()) ; + cat != cat_end ; ++cat) + { + Gtk::TreeModel::Row cat_row = *(model->append(us->children())); + cat_row[columns.col_item] = stringify(*cat); + cat_row[columns.col_data] = BrowseTreeDisplayData::Pointer( + new BrowseTreeDisplayCategoryData(_r, *cat)); + } + } + + public: + BrowseTreeDisplayRepositoryData(const RepositoryName & r) : + _r(r) + { + } + + virtual void display(InformationTree * const information_tree) const + { + information_tree->show_repository(_r); + } + + virtual void sync() const + { + OurSyncTask task; + task.add_target(stringify(_r)); + task.execute(); + } + + }; +} + +BrowseTreeDisplayData::BrowseTreeDisplayData() : + _has_children(false) +{ +} + +BrowseTreeDisplayData::~BrowseTreeDisplayData() +{ +} + + +BrowseTreeColumns::BrowseTreeColumns() +{ + add(col_item); + add(col_data); +} + +BrowseTreeColumns::~BrowseTreeColumns() +{ +} + +namespace paludis +{ + template<> + struct Implementation<BrowseTree> : + InternalCounted<Implementation<BrowseTree> > + { + MainWindow * const main_window; + InformationTree * const information_tree; + + BrowseTreeColumns columns; + Glib::RefPtr<Gtk::TreeStore> model; + + Gtk::Menu popup_menu; + + pid_t paludis_child; + + Implementation(MainWindow * const m, InformationTree * const i) : + main_window(m), + information_tree(i), + paludis_child(-1) + { + } + + virtual ~Implementation() + { + } + }; +} + +BrowseTree::BrowseTree(MainWindow * const main_window, + InformationTree * const information_tree) : + PrivateImplementationPattern<BrowseTree>(new Implementation<BrowseTree>( + main_window, information_tree)) +{ + _imp->model = Gtk::TreeStore::create(_imp->columns); + set_model(_imp->model); + + Gtk::TreeModel::Row repositories_row = *(_imp->model->append()); + repositories_row[_imp->columns.col_item] = "Repositories"; + repositories_row[_imp->columns.col_data] = BrowseTreeDisplayData::DefaultablePointer( + new BrowseTreeDisplayTopData); + + for (PackageDatabase::RepositoryIterator + r(DefaultEnvironment::get_instance()->package_database()->begin_repositories()), + r_end(DefaultEnvironment::get_instance()->package_database()->end_repositories()) ; + r != r_end ; ++r) + { + Gtk::TreeModel::Row repository_row = *(_imp->model->append(repositories_row.children())); + repository_row[_imp->columns.col_item] = stringify((*r)->name()); + repository_row[_imp->columns.col_data] = BrowseTreeDisplayData::Pointer( + new BrowseTreeDisplayRepositoryData((*r)->name())); + } + + append_column("Item", _imp->columns.col_item); + get_selection()->signal_changed().connect(sigc::mem_fun(*this, &BrowseTree::on_changed)); + Vte::Reaper::get_instance()->signal_child_exited().connect(sigc::mem_fun(*this, &BrowseTree::on_child_process_exited)); + + /* popup menu */ + _imp->popup_menu.items().push_back(Gtk::Menu_Helpers::MenuElem("_Sync", + sigc::mem_fun(*this, &BrowseTree::on_menu_sync))); + _imp->popup_menu.accelerate(*this); +} + +BrowseTree::~BrowseTree() +{ +} + +void +BrowseTree::on_changed() +{ + Gtk::TreeModel::iterator i(get_selection()->get_selected()); + if (i) + { + Gtk::TreeModel::Row row(*i); + BrowseTreeDisplayData::Pointer(row[_imp->columns.col_data])->need_children(_imp->model, + _imp->columns, i); + BrowseTreeDisplayData::Pointer(row[_imp->columns.col_data])->display( + _imp->information_tree); + } +} + +void +BrowseTree::on_menu_sync() +{ + Glib::RefPtr<Gtk::TreeView::Selection> selection(get_selection()); + if (selection) + { + Gtk::TreeModel::iterator i(selection->get_selected()); + if (i) + { + _imp->main_window->set_children_sensitive(false); + + pid_t child(fork()); + if (0 == child) + { + try + { + BrowseTreeDisplayData::Pointer((*i)[_imp->columns.col_data])->sync(); + _exit(0); + } + catch (const SyncFailedError & e) + { + _exit(1); + } + } + else if (-1 == child) + throw InternalError(PALUDIS_HERE, "fork failed"); + else + { + Log::get_instance()->message(ll_debug, lc_no_context, + "Forked child process " + stringify(child)); + _imp->paludis_child = child; + Vte::Reaper::get_instance()->add_child(child); + } + } + } +} + +bool +BrowseTree::on_button_press_event(GdkEventButton * our_event) +{ + bool result(TreeView::on_button_press_event(our_event)); + + if (our_event->type == GDK_BUTTON_PRESS && our_event->button == 3) + _imp->popup_menu.popup(our_event->button, our_event->time); + + return result; +} + +void +BrowseTree::on_child_process_exited(int, int status) +{ + if (-1 == _imp->paludis_child) + return; + + if (0 == status) + Log::get_instance()->message(ll_debug, lc_no_context, "child " + stringify(_imp->paludis_child) + + " exited with success"); + else + Log::get_instance()->message(ll_debug, lc_no_context, "child " + stringify(_imp->paludis_child) + + " exited with failure code " + stringify(status)); + + _imp->paludis_child = -1; + _imp->main_window->set_children_sensitive(true); +} + diff --git a/0.8.0/src/gtkpaludis/browse_tree.hh b/0.8.0/src/gtkpaludis/browse_tree.hh new file mode 100644 index 000000000..e67179209 --- /dev/null +++ b/0.8.0/src/gtkpaludis/browse_tree.hh @@ -0,0 +1,47 @@ +/* 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_SRC_GTKPALUDIS_BROWSE_TREE_HH +#define PALUDIS_GUARD_SRC_GTKPALUDIS_BROWSE_TREE_HH 1 + +#include <gtkmm/treeview.h> +#include <paludis/util/private_implementation_pattern.hh> + +namespace paludis +{ + class InformationTree; + class MainWindow; + + class BrowseTree : + public Gtk::TreeView, + private PrivateImplementationPattern<BrowseTree> + { + public: + BrowseTree(MainWindow * const, InformationTree * const); + ~BrowseTree(); + + virtual void on_changed(); + virtual void on_menu_sync(); + + virtual bool on_button_press_event(GdkEventButton *); + virtual void on_child_process_exited(int, int); + }; +} + +#endif diff --git a/0.8.0/src/gtkpaludis/command_line.cc b/0.8.0/src/gtkpaludis/command_line.cc new file mode 100644 index 000000000..61ae1b4e6 --- /dev/null +++ b/0.8.0/src/gtkpaludis/command_line.cc @@ -0,0 +1,68 @@ +/* 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 "command_line.hh" + +CommandLine::CommandLine() : + ArgsHandler(), + + action_args(this, "Actions", + "Selects which basic action to perform. Up to one action should " + "be specified."), + a_version(&action_args, "version", 'V', "Display program version"), + a_help(&action_args, "help", 'h', "Display program help"), + + general_args(this, "General options", + "Options which are relevant for most or all actions."), + a_log_level(&general_args, "log-level", '\0', "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"), + "qa"), + a_config_suffix(&general_args, "config-suffix", 'c', "Config directory suffix") +{ + add_usage_line("[ general options ]"); + add_usage_line("--version"); + add_usage_line("--help"); +} + +std::string +CommandLine::app_name() const +{ + return "gtkpaludis"; +} + +std::string +CommandLine::app_synopsis() const +{ + return "A graphical interface for the other package mangler"; +} + +std::string +CommandLine::app_description() const +{ + return + "A graphical interface for the paludis package manager."; +} + +CommandLine::~CommandLine() +{ +} + diff --git a/0.8.0/src/gtkpaludis/command_line.hh b/0.8.0/src/gtkpaludis/command_line.hh new file mode 100644 index 000000000..399eb64b3 --- /dev/null +++ b/0.8.0/src/gtkpaludis/command_line.hh @@ -0,0 +1,98 @@ +/* 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_SRC_COMMAND_LINE_HH +#define PALUDIS_GUARD_SRC_COMMAND_LINE_HH 1 + +#include <paludis/args/args.hh> +#include <paludis/util/instantiation_policy.hh> + +/** \file + * Declarations for the CommandLine class. + */ + +/** + * Our command line. + */ +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 General arguments + ///\{ + + /// General arguments. + paludis::args::ArgsGroup general_args; + + /// --log-level + paludis::args::EnumArg a_log_level; + + /// --config-suffix + paludis::args::StringArg a_config_suffix; + + ///\} +}; + +/** + * Show the help message. + */ +struct DoHelp +{ + const std::string message; + + DoHelp(const std::string & m = "") : + message(m) + { + } +}; + +#endif diff --git a/0.8.0/src/gtkpaludis/gtkpaludis.cc b/0.8.0/src/gtkpaludis/gtkpaludis.cc new file mode 100644 index 000000000..f5e1f9323 --- /dev/null +++ b/0.8.0/src/gtkpaludis/gtkpaludis.cc @@ -0,0 +1,292 @@ +/* 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/paludis.hh> +#include <paludis/environment/default/default_environment.hh> +#include <paludis/environment/default/default_config.hh> +#include <paludis/util/log.hh> + +#include <libebt/libebt_version.hh> + +#include <libwrapiter/libwrapiter_version.hh> + +#include <gtkmm/main.h> +#include <gtkmm/messagedialog.h> + +#include <iostream> + +#include "command_line.hh" +#include "main_window.hh" + +using namespace paludis; +using std::cout; +using std::cerr; +using std::endl; + +namespace +{ + struct DoVersion + { + }; + + struct GtkInitFailed : Exception + { + GtkInitFailed() : + Exception ("Couldn't initialize gtk") + { + } + }; + + class TryMain : public Gtk::Main + { + static bool _gtkmm_initialized; + + public: + TryMain(int& argc, char**& argv) : + Gtk::Main() + { + _gtkmm_initialized = gtk_init_check(&argc, &argv); + } + + bool initialized() const + { + return _gtkmm_initialized; + } + + static void run(Gtk::Window& window) + { + if (! _gtkmm_initialized) + throw GtkInitFailed(); + + Gtk::Main::run(window); + } + + static void run() + { + if (! _gtkmm_initialized) + throw GtkInitFailed(); + + Gtk::Main::run(); + } + }; + + + bool TryMain::_gtkmm_initialized; + + void display_version() + { + cout << "gtkpaludis " << 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 << "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; +#if HAVE_SANDBOX + cout << "sandbox: enabled" << endl; +#else + cout << "sandbox: disabled" << endl; +#endif + } +} + +int +main(int argc, char * argv[]) +{ + + Context context("In main program:"); + + TryMain gui_kit(argc, argv); + + try + { + { + Context context_local("When handling command line:"); + CommandLine::get_instance()->run(argc, argv); + + if (CommandLine::get_instance()->a_help.specified()) + throw DoHelp(); + + if (CommandLine::get_instance()->a_version.specified()) + throw DoVersion(); + + 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"); + } + + { + Context context_local("When loading configuration:"); + + std::string paludis_command(argv[0]); + std::string::size_type last_slash(paludis_command.rfind('/')); + if (std::string::npos == last_slash) + last_slash = 0; + if (0 == paludis_command.compare(last_slash, 3, "gtk")) + paludis_command.erase(last_slash, 3); + + if (CommandLine::get_instance()->a_config_suffix.specified()) + { + DefaultConfig::set_config_suffix(CommandLine::get_instance()->a_config_suffix.argument()); + paludis_command.append(" --config-suffix " + + CommandLine::get_instance()->a_config_suffix.argument()); + } + + paludis_command.append(" --log-level " + CommandLine::get_instance()->a_log_level.argument()); + DefaultConfig::get_instance()->set_paludis_command(paludis_command); + } + + { + Context context_local("When displaying main window:"); + + if (! gui_kit.initialized()) + throw GtkInitFailed(); + + TryMain::run(*MainWindow::get_instance()); + } + } + catch (const DoVersion &) + { + display_version(); + 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 << 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 (GtkInitFailed & e) + { + cout << endl; + cerr << "Unhandled exception:" << endl + << " * " << e.backtrace("\n * ") + << e.message() << " (" << e.what() << ")\n" << endl; + + cerr << "Try adjust DISPLAY environment variable or pass --display option\n" << endl; + + return EXIT_FAILURE; + } + catch (const Exception & e) + { + if (gui_kit.initialized()) + { + Gtk::Main::init_gtkmm_internals(); + Gtk::MessageDialog dialog("Unhandled exception", false, Gtk::MESSAGE_ERROR); + dialog.set_secondary_text( + "- " + e.backtrace("\n- ") + e.message() + " (" + e.what() + ")"); + dialog.run(); + } + else + { + cout << endl; + cerr << "Unhandled exception:" << endl + << " * " << e.backtrace("\n * ") + << e.message() << " (" << e.what() << ")" << endl; + } + return EXIT_FAILURE; + } + catch (const std::exception & e) + { + if (gui_kit.initialized()) + { + Gtk::MessageDialog dialog("Unhandled exception", false, Gtk::MESSAGE_ERROR); + dialog.set_secondary_text("Unhandled exception (" + stringify(e.what()) + ")"); + dialog.run(); + } + else + { + cout << endl; + cerr << "Unhandled exception:" << endl + << " * " << e.what() << endl; + } + return EXIT_FAILURE; + } + catch (...) + { + if (gui_kit.initialized()) + { + Gtk::MessageDialog dialog("Unhandled exception", false, Gtk::MESSAGE_ERROR); + dialog.set_secondary_text("Unhandled exception (unknown type)"); + dialog.run(); + } + else + { cout << endl; + cerr << "Unhandled exception:" << endl + << " * Unknown exception type. Ouch..." << endl; + } + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + diff --git a/0.8.0/src/gtkpaludis/information_tree.cc b/0.8.0/src/gtkpaludis/information_tree.cc new file mode 100644 index 000000000..022be1c8d --- /dev/null +++ b/0.8.0/src/gtkpaludis/information_tree.cc @@ -0,0 +1,161 @@ +/* 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 "information_tree.hh" +#include <gtkmm/treestore.h> +#include <paludis/environment/default/default_environment.hh> + +using namespace paludis; + +InformationTreeColumns::InformationTreeColumns() +{ + add(col_key); + add(col_value); +} + +InformationTreeColumns::~InformationTreeColumns() +{ +} + +namespace paludis +{ + template<> + struct Implementation<InformationTree> : + InternalCounted<Implementation<InformationTree> > + { + InformationTreeColumns columns; + Glib::RefPtr<Gtk::TreeStore> model; + }; +} + +InformationTree::InformationTree() : + PrivateImplementationPattern<InformationTree>(new Implementation<InformationTree>) +{ + _imp->model = Gtk::TreeStore::create(_imp->columns); + set_model(_imp->model); + + append_column("Key", _imp->columns.col_key); + append_column("Value", _imp->columns.col_value); +} + +InformationTree::~InformationTree() +{ +} + +void +InformationTree::show_top() +{ + set_model(Glib::RefPtr<Gtk::TreeStore>(0)); + _imp->model = Gtk::TreeStore::create(_imp->columns); + + set_model(_imp->model); +} + +void +InformationTree::show_repository(const RepositoryName & r) +{ + Repository::ConstPointer repo(DefaultEnvironment::get_instance()->package_database()->fetch_repository(r)); + + set_model(Glib::RefPtr<Gtk::TreeStore>(0)); + _imp->model = Gtk::TreeStore::create(_imp->columns); + + Gtk::TreeModel::Row name_row(*(_imp->model->append())); + name_row[_imp->columns.col_key] = "name"; + name_row[_imp->columns.col_value] = stringify(repo->name()); + + RepositoryInfo::ConstPointer info(repo->info(false)); + for (RepositoryInfo::SectionIterator section(info->begin_sections()), + section_end(info->end_sections()) ; section != section_end ; ++section) + { + Gtk::TreeModel::Row section_row(*(_imp->model->append())); + section_row[_imp->columns.col_key] = (*section)->heading(); + + for (RepositoryInfoSection::KeyValueIterator kv((*section)->begin_kvs()), + kv_end((*section)->end_kvs()) ; kv != kv_end ; ++kv) + { + Gtk::TreeModel::Row kv_row(*(_imp->model->append(section_row.children()))); + kv_row[_imp->columns.col_key] = kv->first; + kv_row[_imp->columns.col_value] = kv->second; + } + } + + set_model(_imp->model); +} + +void +InformationTree::show_category(const RepositoryName & r, const CategoryNamePart & c) +{ + Repository::ConstPointer repo(DefaultEnvironment::get_instance()->package_database()->fetch_repository(r)); + + set_model(Glib::RefPtr<Gtk::TreeStore>(0)); + _imp->model = Gtk::TreeStore::create(_imp->columns); + + Gtk::TreeModel::Row name_row(*(_imp->model->append())); + name_row[_imp->columns.col_key] = "name"; + name_row[_imp->columns.col_value] = stringify(c); + + set_model(_imp->model); +} + +void +InformationTree::show_package(const RepositoryName & r, const QualifiedPackageName & q) +{ + Repository::ConstPointer repo(DefaultEnvironment::get_instance()->package_database()->fetch_repository(r)); + + set_model(Glib::RefPtr<Gtk::TreeStore>(0)); + _imp->model = Gtk::TreeStore::create(_imp->columns); + + Gtk::TreeModel::Row name_row(*(_imp->model->append())); + name_row[_imp->columns.col_key] = "name"; + name_row[_imp->columns.col_value] = stringify(q); + + set_model(_imp->model); +} + + +void +InformationTree::show_version(const RepositoryName & r, const QualifiedPackageName & q, + const VersionSpec & v) +{ + Repository::ConstPointer repo(DefaultEnvironment::get_instance()->package_database()->fetch_repository(r)); + + set_model(Glib::RefPtr<Gtk::TreeStore>(0)); + _imp->model = Gtk::TreeStore::create(_imp->columns); + + Gtk::TreeModel::Row name_row(*(_imp->model->append())); + name_row[_imp->columns.col_key] = "name"; + name_row[_imp->columns.col_value] = stringify(q); + + Gtk::TreeModel::Row version_row(*(_imp->model->append())); + version_row[_imp->columns.col_key] = "version"; + version_row[_imp->columns.col_value] = stringify(v); + + VersionMetadata::ConstPointer metadata(repo->version_metadata(q, v)); + + Gtk::TreeModel::Row description_row(*(_imp->model->append())); + description_row[_imp->columns.col_key] = "description"; + description_row[_imp->columns.col_value] = metadata->description; + + Gtk::TreeModel::Row homepage_row(*(_imp->model->append())); + description_row[_imp->columns.col_key] = "homepage"; + description_row[_imp->columns.col_value] = metadata->homepage; + + set_model(_imp->model); +} + diff --git a/0.8.0/src/gtkpaludis/information_tree.hh b/0.8.0/src/gtkpaludis/information_tree.hh new file mode 100644 index 000000000..224c24eea --- /dev/null +++ b/0.8.0/src/gtkpaludis/information_tree.hh @@ -0,0 +1,58 @@ +/* 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_SRC_GTKPALUDIS_INFORMATION_TREE_HH +#define PALUDIS_GUARD_SRC_GTKPALUDIS_INFORMATION_TREE_HH 1 + +#include <gtkmm/treeview.h> +#include <paludis/util/private_implementation_pattern.hh> +#include <paludis/name.hh> +#include <paludis/version_spec.hh> + +namespace paludis +{ + class InformationTreeColumns : + public Gtk::TreeModel::ColumnRecord + { + public: + InformationTreeColumns(); + ~InformationTreeColumns(); + + Gtk::TreeModelColumn<Glib::ustring> col_key; + Gtk::TreeModelColumn<Glib::ustring> col_value; + }; + + class InformationTree : + public Gtk::TreeView, + private PrivateImplementationPattern<InformationTree> + { + public: + InformationTree(); + ~InformationTree(); + + void show_top(); + void show_repository(const RepositoryName &); + void show_category(const RepositoryName &, const CategoryNamePart &); + void show_package(const RepositoryName &, const QualifiedPackageName &); + void show_version(const RepositoryName &, const QualifiedPackageName &, + const VersionSpec &); + }; +} + +#endif diff --git a/0.8.0/src/gtkpaludis/main_window.cc b/0.8.0/src/gtkpaludis/main_window.cc new file mode 100644 index 000000000..15066505c --- /dev/null +++ b/0.8.0/src/gtkpaludis/main_window.cc @@ -0,0 +1,139 @@ +/* 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 "main_window.hh" +#include "browse_tree.hh" +#include "information_tree.hh" +#include "vte_message_window.hh" + +#include <paludis/about.hh> +#include <paludis/util/stringify.hh> + +#include <gtkmm/box.h> +#include <gtkmm/button.h> +#include <gtkmm/entry.h> +#include <gtkmm/frame.h> +#include <gtkmm/label.h> +#include <gtkmm/paned.h> +#include <gtkmm/scrolledwindow.h> +#include <gtkmm/stock.h> +#include <gtkmm/textview.h> + +using namespace paludis; + +namespace paludis +{ + template<> + struct Implementation<MainWindow> : + InternalCounted<MainWindow> + { + Gtk::VBox main_container; + + Gtk::HBox search_container; + Gtk::Label search_label; + Gtk::Entry search_box; + Gtk::Button search_button; + + Gtk::VPaned browse_information_messages_pane; + Gtk::HPaned browse_information_pane; + + Gtk::Frame information_frame; + Gtk::ScrolledWindow information_window; + InformationTree information_tree; + + Gtk::Frame browse_frame; + Gtk::ScrolledWindow browse_window; + BrowseTree browse_tree; + + Gtk::Frame messages_frame; + Gtk::ScrolledWindow messages_window; + VteMessageWindow vte_messages; + + Implementation(MainWindow * const main_window); + }; +} + +Implementation<MainWindow>::Implementation(MainWindow * const main_window) : + main_container(false, 5), + search_container(false, 5), + search_label(" Search: "), + search_button(Gtk::Stock::FIND), + information_frame(" Information: "), + browse_frame(" Browse: "), + browse_tree(main_window, &information_tree), + messages_frame(" Messages: ") +{ +} + +MainWindow::MainWindow() : + PrivateImplementationPattern<MainWindow>(new Implementation<MainWindow>(this)) +{ + set_title("gtkPaludis " + stringify(PALUDIS_VERSION_MAJOR) + "." + + stringify(PALUDIS_VERSION_MINOR) + "." + + stringify(PALUDIS_VERSION_MICRO)); + + set_default_size(600, 400); + set_border_width(5); + + add(_imp->main_container); + + _imp->main_container.pack_start(_imp->search_container, Gtk::PACK_SHRINK); + _imp->main_container.pack_end(_imp->browse_information_messages_pane, Gtk::PACK_EXPAND_WIDGET); + + _imp->search_container.pack_start(_imp->search_label, Gtk::PACK_SHRINK); + _imp->search_container.pack_start(_imp->search_box); + _imp->search_container.pack_end(_imp->search_button, Gtk::PACK_SHRINK); + + _imp->browse_information_messages_pane.pack1(_imp->browse_information_pane); + _imp->browse_information_messages_pane.pack2(_imp->messages_frame); + + _imp->browse_information_pane.pack1(_imp->browse_frame); + _imp->browse_information_pane.pack2(_imp->information_frame); + + _imp->browse_frame.add(_imp->browse_window); + _imp->browse_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + _imp->browse_window.set_border_width(5); + _imp->browse_window.add(_imp->browse_tree); + + _imp->information_frame.add(_imp->information_window); + _imp->information_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + _imp->information_window.set_border_width(5); + _imp->information_window.add(_imp->information_tree); + + _imp->messages_frame.add(_imp->messages_window); + _imp->messages_window.set_border_width(5); + _imp->messages_window.add(_imp->vte_messages); + _imp->messages_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + + show_all_children(); +} + +MainWindow::~MainWindow() +{ +} + +void +MainWindow::set_children_sensitive(bool value) +{ + _imp->browse_tree.set_sensitive(value); + _imp->information_tree.set_sensitive(value); + _imp->search_box.set_sensitive(value); + _imp->search_button.set_sensitive(value); +} + diff --git a/0.8.0/src/gtkpaludis/main_window.hh b/0.8.0/src/gtkpaludis/main_window.hh new file mode 100644 index 000000000..6024075f0 --- /dev/null +++ b/0.8.0/src/gtkpaludis/main_window.hh @@ -0,0 +1,45 @@ +/* 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_SRC_GTKPALUDIS_MAIN_WINDOW_HH +#define PALUDIS_GUARD_SRC_GTKPALUDIS_MAIN_WINDOW_HH 1 + +#include <gtkmm/window.h> +#include <paludis/util/private_implementation_pattern.hh> +#include <paludis/util/instantiation_policy.hh> + +namespace paludis +{ + class MainWindow : + public Gtk::Window, + private PrivateImplementationPattern<MainWindow>, + public InstantiationPolicy<MainWindow, instantiation_method::SingletonAsNeededTag> + { + friend class InstantiationPolicy<MainWindow, instantiation_method::SingletonAsNeededTag>; + + private: + MainWindow(); + virtual ~MainWindow(); + + public: + void set_children_sensitive(bool value); + }; +} + +#endif diff --git a/0.8.0/src/gtkpaludis/message_window.cc b/0.8.0/src/gtkpaludis/message_window.cc new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/0.8.0/src/gtkpaludis/message_window.cc diff --git a/0.8.0/src/gtkpaludis/message_window.hh b/0.8.0/src/gtkpaludis/message_window.hh new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/0.8.0/src/gtkpaludis/message_window.hh diff --git a/0.8.0/src/gtkpaludis/sync.cc b/0.8.0/src/gtkpaludis/sync.cc new file mode 100644 index 000000000..ef2a13376 --- /dev/null +++ b/0.8.0/src/gtkpaludis/sync.cc @@ -0,0 +1,100 @@ +/* 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 "sync.hh" +#include "main_window.hh" + +#include <paludis/environment/default/default_environment.hh> +#include <paludis/util/log.hh> +#include <paludis/syncer.hh> + +#include <list> + +using namespace paludis; + +namespace paludis +{ + template<> + struct Implementation<OurSyncTask> : + InternalCounted<Implementation<OurSyncTask> > + { + std::list<std::string> failed_repositories; + }; +} + +OurSyncTask::OurSyncTask() : + SyncTask(DefaultEnvironment::get_instance()), + PrivateImplementationPattern<OurSyncTask>(new Implementation<OurSyncTask>) +{ +} + +OurSyncTask::~OurSyncTask() +{ +} + +void +OurSyncTask::on_sync_all_pre() +{ +} + +void +OurSyncTask::on_sync_pre(const RepositoryName &) +{ +} + +void +OurSyncTask::on_sync_post(const RepositoryName &) +{ +} + +void +OurSyncTask::on_sync_skip(const RepositoryName &) +{ +} + +void +OurSyncTask::on_sync_succeed(const RepositoryName &) +{ +} + +void +OurSyncTask::on_sync_fail(const RepositoryName & r, const SyncFailedError &) +{ + Log::get_instance()->message(ll_warning, lc_no_context, "Sync of repository '" + + stringify(r) + "' failed"); + PrivateImplementationPattern<OurSyncTask>::_imp->failed_repositories.push_back(stringify(r)); +} + +void +OurSyncTask::on_sync_all_post() +{ +} + +OurSyncTask::FailedIterator +OurSyncTask::begin_failed() const +{ + return FailedIterator(PrivateImplementationPattern<OurSyncTask>::_imp->failed_repositories.begin()); +} + +OurSyncTask::FailedIterator +OurSyncTask::end_failed() const +{ + return FailedIterator(PrivateImplementationPattern<OurSyncTask>::_imp->failed_repositories.end()); +} + diff --git a/0.8.0/src/gtkpaludis/sync.hh b/0.8.0/src/gtkpaludis/sync.hh new file mode 100644 index 000000000..600b66246 --- /dev/null +++ b/0.8.0/src/gtkpaludis/sync.hh @@ -0,0 +1,50 @@ +/* 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_SRC_GTKPALUDIS_SYNC_HH +#define PALUDIS_GUARD_SRC_GTKPALUDIS_SYNC_HH 1 + +#include <paludis/tasks/sync_task.hh> +#include <paludis/util/private_implementation_pattern.hh> + +namespace paludis +{ + class OurSyncTask : + public SyncTask, + private PrivateImplementationPattern<OurSyncTask> + { + public: + OurSyncTask(); + ~OurSyncTask(); + + virtual void on_sync_all_pre(); + virtual void on_sync_pre(const RepositoryName &); + virtual void on_sync_post(const RepositoryName &); + virtual void on_sync_skip(const RepositoryName &); + virtual void on_sync_fail(const RepositoryName &, const SyncFailedError &); + virtual void on_sync_succeed(const RepositoryName &); + virtual void on_sync_all_post(); + + typedef libwrapiter::ForwardIterator<OurSyncTask, const std::string> FailedIterator; + FailedIterator begin_failed() const; + FailedIterator end_failed() const; + }; +} + +#endif diff --git a/0.8.0/src/gtkpaludis/vte_message_window.cc b/0.8.0/src/gtkpaludis/vte_message_window.cc new file mode 100644 index 000000000..e6f8a529e --- /dev/null +++ b/0.8.0/src/gtkpaludis/vte_message_window.cc @@ -0,0 +1,136 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * Copyright (c) 2006 Piotr Rak <piotr.rak@gmail.com> + * + * 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 "vte_message_window.hh" +#include <paludis/util/fd_output_stream.hh> +#include <paludis/util/system.hh> +#include <paludis/util/log.hh> +#include <paludis/util/exception.hh> + +//#ifndef _XOPEN_SOURCE +//#define _XOPEN_SOURCE don't know why vte.h has this defined +//#endif + +#include <cstdlib> +#include <fcntl.h> +#include <iostream> + +namespace +{ + class Pty /* this one should propably go to libpaludisutil */ + { + int _master_fd; + int _slave_fd; + public: + Pty(bool controlling_terminal); + ~Pty(); + + int master_fd() const; + int slave_fd() const; + }; + + Pty::Pty(bool controlling_terminal) : + _master_fd(posix_openpt(O_RDWR | (controlling_terminal ? 0 : O_NOCTTY))) + { + if (0 > _master_fd) + throw paludis::InternalError(PALUDIS_HERE, "posix_openpt failed"); + + char *slave_name(ptsname(_master_fd)); + + try + { + if (0 == slave_name) + throw paludis::InternalError(PALUDIS_HERE, "ptsname failed"); + + if (0 > grantpt(_master_fd)) /* TODO: this one needs something special from user co */ + throw paludis::InternalError(PALUDIS_HERE, "grantpt failed"); + + if (0 > unlockpt(_master_fd)) + throw paludis::InternalError(PALUDIS_HERE, "unlockpt failed"); + + if (-1 == (_slave_fd = open(slave_name, O_RDWR))) + throw paludis::InternalError(PALUDIS_HERE, "open slave terminal failed"); + } + catch (...) + { + close(_master_fd); + throw; + } + } + + Pty::~Pty() + { + close(_master_fd); + close(_slave_fd); + } + + int Pty::master_fd() const + { + return _master_fd; + } + + int Pty::slave_fd() const + { + return _slave_fd; + } + +} /* anonymous namespace */ + +namespace paludis +{ + template <> + struct Implementation<VteMessageWindow> : + public InternalCounted<Implementation<VteMessageWindow> > + { + VteMessageWindow * const owner; + Pty pty; + FDOutputStream stream; + + Implementation(VteMessageWindow *o); + + }; + + Implementation<VteMessageWindow>::Implementation(VteMessageWindow* o) : + InternalCounted<Implementation<VteMessageWindow> >(), + owner(o), + pty(false), + stream(pty.slave_fd()) + { + set_run_command_stdout_fds(pty.slave_fd(), pty.master_fd()); + set_run_command_stderr_fds(pty.slave_fd(), pty.master_fd()); + + Log::get_instance()->set_log_stream(&stream); + Log::get_instance()->message(ll_debug, lc_no_context, "Message window initialized"); + } + + + VteMessageWindow::VteMessageWindow() : + Vte::Terminal(), + PrivateImplementationPattern<VteMessageWindow>(new Implementation<VteMessageWindow>(this)) + { + set_pty(dup(_imp->pty.master_fd())); + } + + VteMessageWindow::~VteMessageWindow() + { + Log::get_instance()->set_log_stream(&std::cerr); + } + +} /* namespace paludis */ + diff --git a/0.8.0/src/gtkpaludis/vte_message_window.hh b/0.8.0/src/gtkpaludis/vte_message_window.hh new file mode 100644 index 000000000..35ee72563 --- /dev/null +++ b/0.8.0/src/gtkpaludis/vte_message_window.hh @@ -0,0 +1,82 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * Copyright (c) 2006 Piotr Rak <piotr.rak@gmail.com> + * + * 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_GTKPALUDIS_VTE_MESSAGE_WINDOW +#define PALUDIS_GUARD_SRC_GTKPALUDIS_VTE_MESSAGE_WINDOW 1 + +#include "vtemm/terminal_widget.hh" +#include <paludis/util/private_implementation_pattern.hh> + +namespace paludis +{ + + class VteMessageWindow : + public Vte::Terminal, + public paludis::PrivateImplementationPattern<VteMessageWindow> + { + public: + VteMessageWindow(); + ~VteMessageWindow(); + }; +} + +#endif /* PALUDIS_GUARD_SRC_GTKPALUDIS_VTE_MESSAGE_WINDOW */ + +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org> + * Copyright (c) 2006 Piotr Rak <piotr.rak@gmail.com> + * + * 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_GTKPALUDIS_VTE_MESSAGE_WINDOW +#define PALUDIS_GUARD_SRC_GTKPALUDIS_VTE_MESSAGE_WINDOW 1 + +#include "terminal_widget.hh" +#include <paludis/util/private_implementation_pattern.hh> + +namespace paludis +{ + + class VteMessageWindow : + public Vte::Terminal, + public paludis::PrivateImplementationPattern<VteMessageWindow> + { + public: + VteMessageWindow(); + ~VteMessageWindow(); + }; +} + +#endif /* PALUDIS_GUARD_SRC_GTKPALUDIS_VTE_MESSAGE_WINDOW */ + diff --git a/0.8.0/src/gtkpaludis/vtemm/Makefile.am b/0.8.0/src/gtkpaludis/vtemm/Makefile.am new file mode 100644 index 000000000..f51639808 --- /dev/null +++ b/0.8.0/src/gtkpaludis/vtemm/Makefile.am @@ -0,0 +1,73 @@ +EXTRA_DIST = \ + terminal_widget.hg terminal_widget.ccg \ + reaper.hg reaper.ccg + +AM_CXXFLAGS = -I$(top_srcdir) \ + @PALUDIS_CXXFLAGS@ \ + @PALUDIS_CXXFLAGS_NO_WOLD_STYLE_CAST@ \ + @PALUDIS_CXXFLAGS_NO_WREDUNDANT_DECLS@ \ + @PALUDIS_CXXFLAGS_NO_WSHADOW@ + +DEFS = \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DGLIBMM_EXCEPTIONS_ENABLED=1 + +vte_generated_sources = \ + terminal_widget.cc terminal_widget.hh private/terminal_widget_p.hh \ + reaper.cc reaper.hh private/reaper_p.hh + +SUBDIRS = defs converts . + +if ENABLE_GTK + +BUILT_SOURCES = terminal_widget.hh reaper.hh $(vte_generated_sources) + +# automake is rather weird on this one... +automake-deps-hack.tmp : + $(MAKE) -C defs + touch $@ + +terminal_widget.hh terminal_widget.cc : terminal_widget.hg terminal_widget.ccg automake-deps-hack.tmp + mkdir -p private + @GMMPROC@ --unwrapped -I converts --defs defs terminal_widget . . + sed -e 's@/\* vim: set @/* vim: set ro @' < ./terminal_widget.h > ./terminal_widget.hh + rm terminal_widget.h + mv ./terminal_widget.cc ./terminal_widget.cc.tmp + sed \ + -e 's@#include <vtemm/terminal_widget.h>@#include "terminal_widget.hh"@' \ + -e 's@#include <vtemm/private/terminal_widget_p.h>@#include "private/terminal_widget_p.hh"@' \ + -e 's@/\* vim: set @/* vim: set ro @' \ + < ./terminal_widget.cc.tmp > ./terminal_widget.cc + rm ./terminal_widget.cc.tmp + mv ./private/terminal_widget_p.h ./private/terminal_widget_p.hh + +reaper.hh reaper.cc : reaper.hg reaper.ccg automake-deps-hack.tmp + mkdir -p private + @GMMPROC@ --unwrapped -I converts --defs defs reaper . . + sed -e 's@/\* vim: set @/* vim: set ro @' < ./reaper.h > ./reaper.hh + rm reaper.h + mv ./reaper.cc ./reaper.cc.tmp + sed \ + -e 's@#include <vtemm/reaper.h>@#include "reaper.hh"@' \ + -e 's@#include <vtemm/private/reaper_p.h>@#include "private/reaper_p.hh"@' \ + -e 's@/\* vim: set @/* vim: set ro @' \ + < ./reaper.cc.tmp > ./reaper.cc + rm ./reaper.cc.tmp + mv ./private/reaper_p.h ./private/reaper_p.hh + +noinst_LIBRARIES = libvtemm.a + +nodist_libvtemm_a_SOURCES = \ + $(vte_generated_sources) + +INCLUDES = $(GTKDEPS_CFLAGS) + +clean-local : + rm -fr private || true + +endif + +CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda $(vte_generated_sources) automake-deps-hack.tmp +MAINTAINERCLEANFILES = Makefile.in + diff --git a/0.8.0/src/gtkpaludis/vtemm/converts/Makefile.am b/0.8.0/src/gtkpaludis/vtemm/converts/Makefile.am new file mode 100644 index 000000000..d9fa379ff --- /dev/null +++ b/0.8.0/src/gtkpaludis/vtemm/converts/Makefile.am @@ -0,0 +1,6 @@ +noinst_DATA = convert.m4 convert_base.m4 +CLEANFILES = *~ +MAINTAINERCLEANFILES = Makefile.in +EXTRA_DIST = $(noinst_DATA) + + diff --git a/0.8.0/src/gtkpaludis/vtemm/converts/convert.m4 b/0.8.0/src/gtkpaludis/vtemm/converts/convert.m4 new file mode 100644 index 000000000..319807ef4 --- /dev/null +++ b/0.8.0/src/gtkpaludis/vtemm/converts/convert.m4 @@ -0,0 +1,30 @@ +dnl $Id: convert.m4,v 1.1.1.1 2003/01/21 13:41:24 murrayc Exp $ + +# Other libraries, such as libgnomeuimm, can provide their own convert.m4 files, +# Maybe choosing to include the same files as this one. + +include(convert_gtkmm.m4) + +_CONV_ENUM(Vte,TerminalEraseBinding) +_CONV_ENUM(Vte,TerminalAntiAlias) + +_EQUAL(glong, long) +_EQUAL(guint, unsigned) + +_CONVERSION(int&, int*, &($3)) +_CONVERSION(long&, glong*, &($3)) +_CONVERSION(return-char*, char*, ($3)) + +# Gtk conversions +_CONVERSION(const Gtk::MenuShell&, GtkMenuShell*, (const_cast<Gtk::MenuShell&>($3)).gobj()) + +# Gdk conversions +_CONVERSION(const Gdk::Color&, const GdkColor*, ($3).gobj()) +_CONVERSION(Gdk::Color&, GdkColor*, ($3).gobj()) +_CONVERSION(Gdk::Cursor&, GdkCursor*, ($3).gobj()) + +# Pango conversions +_CONVERSION(const Pango::FontDescription&, const PangoFontDescription*, ($3).gobj()) +_CONVERSION(const PangoFontDescription*, const Pango::FontDescription, Glib::wrap(const_cast<PangoFontDescription*>(($3)), true)) + + diff --git a/0.8.0/src/gtkpaludis/vtemm/converts/convert_base.m4 b/0.8.0/src/gtkpaludis/vtemm/converts/convert_base.m4 new file mode 100644 index 000000000..feaf583ca --- /dev/null +++ b/0.8.0/src/gtkpaludis/vtemm/converts/convert_base.m4 @@ -0,0 +1,69 @@ +dnl $Id: convert_base.m4,v 1.1.1.1 2003/01/21 13:41:24 murrayc Exp $ + +# +# Define a hashing for names +# +define(`__HASH',`__`'m4_translit(`$*',`ABCDEFGHIJKLMNOPQRSTUVWXYZ<>[]&*, ',`abcdefghijklmnopqrstuvwxyzVBNMRSC_')`'') +define(`__EQUIV',`m4_ifdef(EV`'__HASH(`$1'),EV`'__HASH(`$1'),`$1')') + +define(`__HASH2',`dnl +pushdef(`__E1',__EQUIV(`$1'))pushdef(`__E2',__EQUIV(`$2'))dnl +m4_ifelse(__E1,__E2,`__EQ',__HASH(__E1)`'__HASH(__E2))`'dnl +popdef(`__E1')popdef(`__E2')`'') + +define(`CF__EQ',`$3') + +# +# _CONVERT(ctype, cpptype, name, wrap_line) +# Print the conversion from ctype to cpptype +define(`_CONVERT',`dnl +pushdef(`__COV',`CF`'__HASH2(`$1',`$2')')dnl +m4_ifdef(__COV,`m4_indir(__COV,`$1',`$2',`$3')',` +m4_errprint(`No conversion from $1 to $2 defined (line: $4, parameter name: $3) +') +m4_m4exit(1) +')`'dnl +') + + +# +# Functions for populating the tables. +# +define(`_CONVERSION',` +m4_ifelse(`$3',,,`define(CF`'__HASH2(`$1',`$2'),`$3')') +') + +define(`_EQUAL',`define(EV`'__HASH(`$1'),`$2')') + +/*******************************************************************/ + + +define(`__ARG3__',`$`'3') +define(`_CONV_ENUM',`dnl +_CONVERSION(`$1$2', `$2', (($2)(__ARG3__))) +_CONVERSION(`$1$2', `$1::$2', (($1::$2)(__ARG3__))) +_CONVERSION(`$2', `$1$2', (($1$2)(__ARG3__))) +_CONVERSION(`$1::$2', `$1$2', (($1$2)(__ARG3__))) +')dnl + +# e.g. Glib::RefPtr<Gdk::Something> to GdkSomething* +define(`__CONVERT_REFPTR_TO_P',`Glib::unwrap($`'3)') + +# e.g. Glib::RefPtr<const Gdk::Something> to GdkSomething* +#define(`__CONVERT_CONST_REFPTR_TO_P',`const_cast<$`'2>($`'3->gobj())') +define(`__CONVERT_CONST_REFPTR_TO_P',`const_cast<$`'2>(Glib::unwrap($`'3))') + +# The Sun Forte compiler doesn't seem to be able to handle these, so we are using the altlernative, __CONVERT_CONST_REFPTR_TO_P_SUN. +# The Sun compiler gives this error, for instance: +#Â "widget.cc", line 4463: Error: Overloading ambiguity between "Glib::unwrap<Gdk::Window>(const Glib::RefPtr<const Gdk::Window>&)" and +# "Glib::unwrap<const Gdk::Window>(const Glib::RefPtr<const Gdk::Window>&)". +# +define(`__CONVERT_CONST_REFPTR_TO_P_SUN',`const_cast<$`'2>(Glib::unwrap<$1>($`'3))') + + +include(convert_gtk.m4) +include(convert_pango.m4) +include(convert_gdk.m4) +include(convert_atk.m4) +include(convert_glib.m4) + diff --git a/0.8.0/src/gtkpaludis/vtemm/defs/Makefile.am b/0.8.0/src/gtkpaludis/vtemm/defs/Makefile.am new file mode 100644 index 000000000..7fa3843ed --- /dev/null +++ b/0.8.0/src/gtkpaludis/vtemm/defs/Makefile.am @@ -0,0 +1,51 @@ +vte_defs_included = \ + vte_methods.defs \ + vte_vfuncs.defs \ + vte_enums.defs \ + vte_signals.defs + +vte_defs = \ + $(vte_defs_included) \ + vte.defs + +if ENABLE_GTK + +noinst_DATA = $(vte_defs) +noinst_PROGRAMS = force_automake_to_include_cxxcompile + +endif + +INCLUDES = $(GTKDEPS_CFLAGS) + +force_automake_to_include_cxxcompile_SOURCES = force_automake_to_include_cxxcompile.cc + +force_automake_to_include_cxxcompile.cc : + echo 'int main(int, char *[]) { }' > $@ + +generate_defs_vte : generate_defs_vte.cc + $(CXXCOMPILE) $(GTKDEPS_LIBS) -lglibmm_generate_extra_defs-2.4 -o $@ $< + +CLEANFILES = *~ force_automake_to_include_cxxcompile.cc generate_defs_vte +MAINTAINERCLEANFILES = Makefile.in $(vte_defs) + +vte_methods.defs : + if ! python `pkg-config --variable=datadir pygtk-2.0`/pygtk/2.0/codegen/h2def.py \ + `pkg-config --variable=includedir vte`/vte/*.h \ + > $@ ; then rm $@ ; false ; fi + +vte_enums.defs : + if ! perl $(srcdir)/enum.pl `pkg-config --variable=includedir vte`/vte/*.h > $@ ; \ + then rm $@ ; false ; fi + +vte_signals.defs : generate_defs_vte + ./generate_defs_vte | sed -e 's~const-gchar\*~gchar*~' > $@ + +vte.defs : + echo > $@ + for a in $(vte_defs_included) ; do echo "(include $${a})" >> $@ ; done + +vte_vfuncs.defs : + touch $@ + +EXTRA_DIST = enum.pl generate_defs_vte.cc + diff --git a/0.8.0/src/gtkpaludis/vtemm/defs/enum.pl b/0.8.0/src/gtkpaludis/vtemm/defs/enum.pl new file mode 100644 index 000000000..df41545dc --- /dev/null +++ b/0.8.0/src/gtkpaludis/vtemm/defs/enum.pl @@ -0,0 +1,230 @@ +#! /usr/bin/perl + +# The lisp definitions for flags does not include order. +# thus we must extract it ourselves. +# Usage: ./enum.pl /gnome/head/cvs/gconf/gconf/*.h > gconf_enums.defs + + +my %token; +$module="none"; + +while ($ARGV[0] =~ /^--(\S+)/) +{ + shift @ARGV; + $module=shift @ARGV if ($1 eq "module"); + if ($1 eq "help") + { + print "enum.pl [--module modname] header_files ....\n"; + exit 0; + } +} + +foreach $file (@ARGV) +{ + &parse($file); +} + +exit; + + + +# parse enums from C +sub parse +{ + my ($file)=@_; + + $from=0; + open(FILE,$file); + + $enum=0; + $deprecated=0; + $comment=0; + + while(<FILE>) + { + if($comment) + { + # end of multiline comment + $comment = 0 if(/\*\//); + next; + } + + $deprecated = 1 if(s/^#ifndef [A-Z_]+_DISABLE_DEPRECATED//); + + ++$deprecated if($deprecated > 0 && /^#\s*if/); + --$deprecated if($deprecated > 0 && /^#\s*endif/); + + next if($deprecated > 0); + + # filter single-line comments + s/\/\*.*\*\///g; + + # begin of multiline comment + if(/\/\*/) + { + $comment = 1; + next; + } + + s/','/\%\%COMMA\%\%/; + s/'}'/\%\%RBRACE\%\%/; + if (/^typedef enum/ ) + { + print ";; From $file\n\n" if (!$from); + $from=1; + $enum=1; + next; + } + + if ($enum && /\}/) + { + $enum=0; + &process($line,$_); + $line=""; + } + $line.=$_ if ($enum); + } +} + + +# convert enums to lisp +sub process +{ + my ($line,$def)=@_; + + $def=~s/\s*\}\s*//g; + $def=~s/\s*;\s*$//; + my $c_name=$def; + + $line=~s/\s+/ /g; + $line=~s/\/\*.*\*\///g; + $line=~s/\s*{\s*//; + + my $entity = "enum"; + $c_name =~ /^([A-Z][a-z]*)/; + $module = $1; + $def =~ s/$module//; + + @c_name=(); + @name=(); + @number=(); + + $val=0; + foreach $i (split(/,/,$line)) + { + $i=~s/^\s+//; + $i=~s/\s+$//; + if ($i =~ /^\S+$/) + { + push(@c_name,$i); + push(@number,sprintf("%d",$val)); + $token{$i}=$val; + } + elsif ($i =~ /^(\S+)\s*=\s*(0x[0-9a-fA-F]+)$/ || + $i =~ /^(\S+)\s*=\s*(-?[0-9]+)$/ || + $i =~ /^(\S+)\s*=\s*(1\s*<<\s*[0-9]+)$/ + ) + { + my ($tmp1, $tmp2) = ($1, $2); + push(@c_name, $tmp1); + eval("\$val = $tmp2;"); + $entity = "flags" if($tmp2 =~ /^1\s*<</ || $tmp2 =~ /^0x/); + push(@number, $tmp2); + $token{$tmp1} = $tmp2; + } + elsif ($i =~ /^(\S+)\s*=\s*([ _x0-9a-fA-Z|()~]+)$/) + { + my ($tmp1, $tmp2) = ($1, $2); + push(@c_name, $tmp1); + $tmp2 =~ s/([A-Z_]+)/($token{$1})/; + eval("\$val = $tmp2;"); + $val = "#error" if(!$val); + $val = sprintf("0x%X", $val) if($entity eq "flags"); + push(@number, $val); + $token{$tmp1} = $val; + } + elsif ($i =~ /^(\S+)\s*=\s*'(.)'$/) + { + push(@c_name,$1); + push(@number,"\'$2\'"); + $val=ord($2); + $token{$1}=$val; + } + elsif ($i =~ /^(\S+)\s*=\s*(\%\%[A-Z]+\%\%)$/) + { + $tmp=$1; + $_=$2; + s/\%\%COMMA\%\%/,/; + s/\%\%RBRACE\%\%/]/; + push(@c_name,$tmp); + push(@number,"\'$_\'"); + $val=ord($_); + $token{$tmp}=$val; + } + else + { + #print STDERR "$i\n"; + } + $val++; + } + + # remove the prefix to form names + &form_names(\@name,\@c_name); + + my $format = "%d"; + $format = "0x%X" if($entity eq "flags"); + + # evaluate any unevaluated values + my $j; + for ($j=0;$j<$#number+1;$j++) + { + if ($number[$j]=~/\$/) + { + $number[$j]=sprintf($format, eval($number[$j])); + } + } + + #print ";; Enum $def\n\n"; + print "(define-$entity-extended $def\n"; + print " (in-module \"$module\")\n"; + print " (c-name \"$c_name\")\n"; + + print " (values\n"; + for ($j=0;$j<$#c_name+1;$j++) + { + print " \'(\"$name[$j]\" \"$c_name[$j]\""; + print " \"$number[$j]\"" if ($number[$j] ne ""); + print ")\n"; + } + print " )\n"; + print ")\n\n"; +} + + +sub form_names +{ + my ($name,$c_name)=@_; + + my $len=length($$c_name[0]) - 1; + my $j; + for ($j=0;$j<$#c_name;$j++) + { + while (substr($$c_name[$j],$len-1,1) ne "_" || + substr($$c_name[$j],0,$len) ne substr($$c_name[$j+1],0,$len)) + { + $len--; + } + #print substr($$c_name[$j],0,$len),"\n"; + } + + my $prefix=substr($$c_name[0],0,$len); + + for ($j=0;$j<$#c_name+1;$j++) + { + $_=$$c_name[$j]; + s/^$prefix//; + tr/A-Z_/a-z-/; + push(@$name,$_); + } + +} diff --git a/0.8.0/src/gtkpaludis/vtemm/defs/generate_defs_vte.cc b/0.8.0/src/gtkpaludis/vtemm/defs/generate_defs_vte.cc new file mode 100644 index 000000000..20c9b5c68 --- /dev/null +++ b/0.8.0/src/gtkpaludis/vtemm/defs/generate_defs_vte.cc @@ -0,0 +1,36 @@ +/* $Id: generate_defs_gtk.cc,v 1.22 2006/05/16 18:03:21 murrayc Exp $ */ + +/* generate_defs_gtk.cc + * + * Copyright (C) 2001 The Free Software Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "glibmm_generate_extra_defs/generate_extra_defs.h" +#include <gdk/gdk.h> +#include <gtk/gtk.h> +#include <vte/vte.h> +#include <vte/reaper.h> + +int main (int argc, char *argv[]) +{ + gtk_init(&argc, &argv); + +std::cout << get_defs(VTE_TYPE_TERMINAL) + << get_defs(VTE_TYPE_REAPER); + + return 0; +} diff --git a/0.8.0/src/gtkpaludis/vtemm/reaper.ccg b/0.8.0/src/gtkpaludis/vtemm/reaper.ccg new file mode 100644 index 000000000..e2f1164aa --- /dev/null +++ b/0.8.0/src/gtkpaludis/vtemm/reaper.ccg @@ -0,0 +1,65 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Piotr Rak <piotr.rak@gmail.com> + * + * 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 <vte/reaper.h> +#include <paludis/util/exception.hh> + +namespace +{ + + void Reaper_proxy_signal_child_exited(GObject*, int pid, int status, gpointer data) + { + #ifdef GLIBMM_EXCEPTIONS_ENABLED + try + { + #endif //GLIBMM_EXCEPTIONS_ENABLED + if (Vte::Reaper::get_instance() == data) //ignore signals connected using c api + Vte::Reaper::get_instance()->signal_child_exited().emit(pid, status); + #ifdef GLIBMM_EXCEPTIONS_ENABLED + } + catch(...) + { + Glib::exception_handlers_invoke(); + } + #endif //GLIBMM_EXCEPTIONS_ENABLED + } +} /* anonymous namspace */ + +namespace Vte +{ + + Reaper::Reaper() : + Glib::Object(reinterpret_cast<GObject*>(::vte_reaper_get())) + { + //TODO: looks like vte-0.13.3 has child-exited renamed abi/api breakage?? + //propably shoud be also unregistred if Reaper will stop be singleton + g_signal_connect(G_OBJECT(gobj()), "child-exited", G_CALLBACK(Reaper_proxy_signal_child_exited) , this); + } + + int Reaper::add_child(GPid pid) + { + return vte_reaper_add_child(pid); + } + + sigc::signal<void, int, int>& Reaper::signal_child_exited() + { + return _signal_child_exited; + } +} + diff --git a/0.8.0/src/gtkpaludis/vtemm/reaper.hg b/0.8.0/src/gtkpaludis/vtemm/reaper.hg new file mode 100644 index 000000000..3447636dc --- /dev/null +++ b/0.8.0/src/gtkpaludis/vtemm/reaper.hg @@ -0,0 +1,50 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Piotr Rak <piotr.rak@gmail.com> + * + * 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 <sys/types.h> +#include <paludis/util/instantiation_policy.hh> +#include <paludis/util/private_implementation_pattern.hh> +#include <glibmm/object.h> +#include <sigc++/sigc++.h> + +_DEFS(vtemm,vte) +_PINCLUDE(glibmm/private/object_p.h) + +namespace Vte +{ + class Reaper : + public Glib::Object, + public paludis::InstantiationPolicy<Reaper, paludis::instantiation_method::SingletonAsNeededTag> + + { + friend class paludis::InstantiationPolicy<Reaper, paludis::instantiation_method::SingletonAsNeededTag>; + + sigc::signal<void, int, int> _signal_child_exited; + + _CLASS_GOBJECT(Reaper,VteReaper,VTE_REAPER,Glib::Object,GObject) + + Reaper(); + + public: + + int add_child(GPid pid); + sigc::signal<void, int, int>& signal_child_exited(); + + }; +} diff --git a/0.8.0/src/gtkpaludis/vtemm/terminal_widget.ccg b/0.8.0/src/gtkpaludis/vtemm/terminal_widget.ccg new file mode 100644 index 000000000..74ff4a981 --- /dev/null +++ b/0.8.0/src/gtkpaludis/vtemm/terminal_widget.ccg @@ -0,0 +1,159 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Piotr Rak <piotr.rak@gmail.com> + * + * 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 <vte/vte.h> + +namespace +{ + +gboolean proxy_slot_selected_callback(VteTerminal * /* term */ , glong column, glong row, gpointer data) +{ + typedef Vte::Terminal::SlotIsSelected SlotType; + SlotType& slot(*static_cast<SlotType*>(data)); + + #ifdef GLIBMM_EXCEPTIONS_ENABLED + try + { + #endif //GLIBMM_EXCEPTIONS_ENABLED + return slot(column, row); + #ifdef GLIBMM_EXCEPTIONS_ENABLED + } + catch(...) + { + Glib::exception_handlers_invoke(); + } + #endif //GLIBMM_EXCEPTIONS_ENABLED + + return 0; +} + +} /* anonymous namespace */ + + +namespace Vte +{ + +CharAttributes::CharAttributes(VteCharAttributes* obj) : + _gobject(new VteCharAttributes(*obj)) +{ +} + +CharAttributes::~CharAttributes() +{ + delete _gobject; +} + +CharAttributes::CharAttributes(const CharAttributes& rhs) : + _gobject(new VteCharAttributes(*rhs._gobject)) +{ +} + +CharAttributes& CharAttributes::operator= (const CharAttributes& rhs) +{ + if (this != &rhs) + { + delete _gobject; + _gobject = new VteCharAttributes(*rhs._gobject); + } + return *this; +} + +int CharAttributes::row() const +{ + return _gobject->row; +} + +int CharAttributes::column() const +{ + return _gobject->column; +} + +Gdk::Color CharAttributes::foreground() const +{ + return Gdk::Color(&_gobject->fore, true); +} + +Gdk::Color CharAttributes::background() const +{ + return Gdk::Color(&_gobject->back, true); +} + +bool CharAttributes::underline() const +{ + return _gobject->underline; +} + +bool CharAttributes::strikethrough() const +{ + return _gobject->strikethrough; +} + +char* Terminal::get_text(const Terminal::SlotIsSelected& slot, std::vector<CharAttributes>& attributes) +{ + GArray* garray(g_array_new(false, true, sizeof(VteCharAttributes))); + Terminal::SlotIsSelected slot_copy(slot); + + char * result(vte_terminal_get_text(gobj(), &proxy_slot_selected_callback, &slot_copy, garray)); + + for (size_t i=0; i< garray->len; ++i) + { + attributes.push_back(new VteCharAttributes(g_array_index(garray, VteCharAttributes, i))); //TODO suboptimal deep copy + } + + g_array_free(garray, false); + + return result; +} + +char* Terminal::get_text_include_trailing_spaces(const Terminal::SlotIsSelected& slot, std::vector<CharAttributes>& attributes) +{ + GArray* garray(g_array_new(false, true, sizeof(VteCharAttributes))); + Terminal::SlotIsSelected slot_copy(slot); + + char * result(vte_terminal_get_text_include_trailing_spaces(gobj(), + &proxy_slot_selected_callback, &slot_copy, garray)); + + for (size_t i=0; i< garray->len; ++i) + { + attributes.push_back(new VteCharAttributes(g_array_index(garray, VteCharAttributes, i))); //TODO suboptimal deep copy + } + + g_array_free(garray, true); + + return result; +} + +char* Terminal::get_text_range(long start_row, long start_col, long end_row, long end_col, const SlotIsSelected& slot, std::vector<CharAttributes>& attributes) +{ + GArray* garray(g_array_new(false, true, sizeof(VteCharAttributes))); + Terminal::SlotIsSelected slot_copy(slot); + + char * result(vte_terminal_get_text_range(gobj(),start_row, start_col, end_row, end_col, + &proxy_slot_selected_callback, &slot_copy, garray)); + + for (size_t i=0; i< garray->len; ++i) + { + attributes.push_back(new VteCharAttributes(g_array_index(garray, VteCharAttributes, i))); //TODO suboptimal deep copy + } + + g_array_free(garray, true); + + return result; +} + +} /* namespace Vte */ diff --git a/0.8.0/src/gtkpaludis/vtemm/terminal_widget.hg b/0.8.0/src/gtkpaludis/vtemm/terminal_widget.hg new file mode 100644 index 000000000..956a29396 --- /dev/null +++ b/0.8.0/src/gtkpaludis/vtemm/terminal_widget.hg @@ -0,0 +1,181 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Piotr Rak <piotr.rak@gmail.com> + * + * 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 <gtkmm/widget.h> +#include <gtkmm/menushell.h> +#include <gtkmm/adjustment.h> +#include <gdkmm/cursor.h> +#include <pangomm/fontdescription.h> + +#include <vector> + +_DEFS(vtemm,vte) +_PINCLUDE(gtkmm/private/widget_p.h) + +/* we don't want whole vte.h in this file */ +typedef struct _VteCharAttributes VteCharAttributes; + +namespace Vte +{ + + +class CharAttributes +{ +private: + VteCharAttributes * _gobject; + +public: + CharAttributes(VteCharAttributes *obj); + CharAttributes(const CharAttributes&); + + ~CharAttributes(); + + CharAttributes& operator= (const CharAttributes&); + + int row() const; + int column() const; + Gdk::Color foreground() const; + Gdk::Color background() const; + bool underline() const; + bool strikethrough() const; +}; + +_WRAP_ENUM(TerminalEraseBinding, VteTerminalEraseBinding) +_WRAP_ENUM(TerminalAntiAlias, VteTerminalAntiAlias) + +class Terminal : + public Gtk::Widget +{ + +_CLASS_GTKOBJECT(Terminal,VteTerminal,VTE_TERMINAL,Gtk::Widget,GtkWidget) +public: + +typedef sigc::slot<bool, long, long> SlotIsSelected; + +_CTOR_DEFAULT + +_WRAP_METHOD(void im_append_menuitems(const Gtk::MenuShell& menushell), vte_terminal_im_append_menuitems) +_WRAP_METHOD(pid_t fork_command(const char* command, char** argv, char** envv, const char* directory, bool lastlog, bool utmp, bool wtmp), vte_terminal_fork_command) +_WRAP_METHOD(pid_t forkpty(char** env, const char* directory, bool lastlog, bool utmp, bool wtmp), vte_terminal_forkpty) +_WRAP_METHOD(void set_pty(int pty_master), vte_terminal_set_pty) +_WRAP_METHOD(void feed(const char* data, glong length), vte_terminal_feed) +_WRAP_METHOD(void feed_child(const char* text, glong length), vte_terminal_feed_child) +_WRAP_METHOD(void feed_child_binary(const char* data, glong length), vte_terminal_feed_child_binary) +_WRAP_METHOD(void copy_clipboard(), vte_terminal_copy_clipboard) +_WRAP_METHOD(void paste_clipboard(), vte_terminal_paste_clipboard) +_WRAP_METHOD(void copy_primary(), vte_terminal_copy_primary) +_WRAP_METHOD(void paste_primary(), vte_terminal_paste_primary) +_WRAP_METHOD(void set_size(glong columns, glong rows), vte_terminal_set_size) +_WRAP_METHOD(void set_audible_bell(bool is_audible), vte_terminal_set_audible_bell) +_WRAP_METHOD(bool get_audible_bell(), vte_terminal_get_audible_bell) +_WRAP_METHOD(void set_visible_bell(bool is_visible), vte_terminal_set_visible_bell) +_WRAP_METHOD(bool get_visible_bell(), vte_terminal_get_visible_bell) +_WRAP_METHOD(void set_allow_bold(bool allow_bold), vte_terminal_set_allow_bold) +_WRAP_METHOD(bool get_allow_bold(), vte_terminal_get_allow_bold) +_WRAP_METHOD(void set_scroll_on_output(bool scroll), vte_terminal_set_scroll_on_output) +_WRAP_METHOD(void set_scroll_on_keystroke(bool scroll), vte_terminal_set_scroll_on_keystroke) +_WRAP_METHOD(void set_color_bold(const Gdk::Color& bold), vte_terminal_set_color_bold ) +_WRAP_METHOD(void set_color_foreground(const Gdk::Color& foreground), vte_terminal_set_color_foreground) +_WRAP_METHOD(void set_color_background(const Gdk::Color& background), vte_terminal_set_color_background) +_WRAP_METHOD(void set_color_dim(const Gdk::Color& dim), vte_terminal_set_color_dim) +_WRAP_METHOD(void set_color_cursor(const Gdk::Color& cursor), vte_terminal_set_color_cursor) +_WRAP_METHOD(void set_color_highlight(const Gdk::Color& highlight), vte_terminal_set_color_highlight) +_WRAP_METHOD(void set_colors(const Gdk::Color& foreground, const Gdk::Color& background, const Gdk::Color& palete_size, glong palette_size), vte_terminal_set_colors) +_WRAP_METHOD(void set_default_colors(), vte_terminal_set_default_colors) +_WRAP_METHOD(void set_background_image(Glib::RefPtr<Gdk::Pixbuf> pixbuf), vte_terminal_set_background_image) +_WRAP_METHOD(void set_background_image_file(const char* path), vte_terminal_set_background_image_file) +_WRAP_METHOD(void set_background_saturation(double saturation), vte_terminal_set_background_saturation) +_WRAP_METHOD(void set_background_transparent(bool transparent), vte_terminal_set_background_transparent) +_WRAP_METHOD(void set_background_tint_color(const Gdk::Color& color), vte_terminal_set_background_tint_color) +_WRAP_METHOD(void set_scroll_background(bool scroll), vte_terminal_set_scroll_background) +_WRAP_METHOD(void set_cursor_blinks(bool blink), vte_terminal_set_cursor_blinks) +_WRAP_METHOD(void set_scrollback_lines(long lines), vte_terminal_set_scrollback_lines) +_WRAP_METHOD(void set_font(const Pango::FontDescription& font_desc), vte_terminal_set_font) +_WRAP_METHOD(void set_font_from_string(const char* name), vte_terminal_set_font_from_string) +_WRAP_METHOD(void set_font_from_string_full(const char* name, TerminalAntiAlias antialas), vte_terminal_set_font_from_string_full) +_WRAP_METHOD(void set_font_full(const Pango::FontDescription& font_desc, TerminalAntiAlias antialas), vte_terminal_set_font_full) +_WRAP_METHOD(const Pango::FontDescription get_font(), vte_terminal_get_font) +_WRAP_METHOD(bool get_using_xft(), vte_terminal_get_using_xft) +_WRAP_METHOD(bool get_has_selection(), vte_terminal_get_has_selection) +_WRAP_METHOD(void set_word_chars(const char* spec), vte_terminal_set_word_chars) +_WRAP_METHOD(bool is_word_char(gunichar), vte_terminal_is_word_char) +_WRAP_METHOD(void set_backspace_binding(TerminalEraseBinding binding), vte_terminal_set_backspace_binding) +_WRAP_METHOD(void set_delete_binding(TerminalEraseBinding binding), vte_terminal_set_delete_binding) +_WRAP_METHOD(void set_mouse_autohide(bool setting), vte_terminal_set_mouse_autohide) +_WRAP_METHOD(bool get_mouse_autohide(), vte_terminal_get_mouse_autohide) +_WRAP_METHOD(void reset(bool full, bool clear_history), vte_terminal_reset) +//_WRAP_METHOD(char* get_text(bool (*is_selected) (glong column,glong row,gpointer data), gpointer data, GArray *attributes), vte_terminal_get_text) //Manualy wrapped below +//_WRAP_METHOD(char* get_text_range(glong start_row, glong start_col, glong end_row, glong end_col, gboolean (*is_selected) (glong column,glong row,gpointer data), gpointer data, GArray *attributes), vte_terminal_get_text_range) //Manualy wrapped bellow +_WRAP_METHOD(void get_cursor_position(long& column, long& row), vte_terminal_get_cursor_position) +_WRAP_METHOD(void match_clear_all(), vte_terminal_match_clear_all) +_WRAP_METHOD(int match_add(const char* match), vte_terminal_match_add) +_WRAP_METHOD(void match_remove(int tag), vte_terminal_match_remove) +_WRAP_METHOD(char* match_check(glong column, glong row, int& tag), vte_terminal_match_check) +_WRAP_METHOD(void match_set_cursor(int tag, Gdk::Cursor& ), vte_terminal_match_set_cursor) +_WRAP_METHOD(void match_set_cursor_type(int tag, Gdk::CursorType), vte_terminal_match_set_cursor_type) +_WRAP_METHOD(void set_emulation(const char* emulation), vte_terminal_set_emulation) +_WRAP_METHOD(const char* get_emulation(), vte_terminal_get_emulation) +_WRAP_METHOD(const char* get_default_emulation(), vte_terminal_get_default_emulation) +_WRAP_METHOD(void set_encoding(const char* codeset), vte_terminal_set_encoding) +_WRAP_METHOD(const char* get_encoding(), vte_terminal_get_encoding) +_WRAP_METHOD(const char* get_status_line(), vte_terminal_get_status_line) +_WRAP_METHOD(void get_padding(int& xpad, int& ypad), vte_terminal_get_padding) +_WRAP_METHOD(Gtk::Adjustment* get_adjustment(), vte_terminal_get_adjustment) +_WRAP_METHOD(glong get_char_ascent(), vte_terminal_get_char_ascent) +_WRAP_METHOD(glong get_char_descent(), vte_terminal_get_char_descent) +_WRAP_METHOD(glong get_char_height(), vte_terminal_get_char_height) +_WRAP_METHOD(glong get_char_width(), vte_terminal_get_char_width) +_WRAP_METHOD(glong get_column_count(), vte_terminal_get_column_count) +_WRAP_METHOD(const char* get_icon_title(), vte_terminal_get_icon_title) +_WRAP_METHOD(glong get_row_count(), vte_terminal_get_row_count) +_WRAP_METHOD(const char* get_window_title(), vte_terminal_get_window_title) + +_WRAP_SIGNAL(void char_size_changed(unsigned w, unsigned h), "char-size-changed") +_WRAP_SIGNAL(void child_exited(), "child-exited") +_WRAP_SIGNAL(void commit(gchar* text, unsigned length), "commit") +_WRAP_SIGNAL(void contents_changed(), "contents-changed") +_WRAP_SIGNAL(void cursor_moved(), "cursor-moved") +_WRAP_SIGNAL(void decrease_font_size(), "decrease-font-size") +_WRAP_SIGNAL(void deiconify_window(), "deiconify-window") +_WRAP_SIGNAL(void emulation_changed(), "emulation-changed") +_WRAP_SIGNAL(void encoding_changed(), "encoding-changed") +_WRAP_SIGNAL(void eof(), "eof") +_WRAP_SIGNAL(void icon_title_changed(), "icon-title-changed") +_WRAP_SIGNAL(void iconify_window(), "iconify-window") +_WRAP_SIGNAL(void increase_font_size(), "increase-font-size") +_WRAP_SIGNAL(void lower_window(), "lower-window") +_WRAP_SIGNAL(void maximize_window(), "maximize-window") +_WRAP_SIGNAL(void move_window(unsigned x, unsigned y), "move-window") +_WRAP_SIGNAL(void raise_window(), "raise-window") +_WRAP_SIGNAL(void refresh_window(), "refresh-window") +_WRAP_SIGNAL(void resize_window(unsigned w, unsigned h), "resize-window") +_WRAP_SIGNAL(void restore_window(), "restore-window") +_WRAP_SIGNAL(void selection_changed(), "selection-changed") +_WRAP_SIGNAL(void status_line_changed(), "status-line-changed") +_WRAP_SIGNAL(void text_deleted(), "text-deleted") +_WRAP_SIGNAL(void text_inserted(), "text-inserted") +_WRAP_SIGNAL(void text_modified(), "text-modified") +_WRAP_SIGNAL(void text_scrolled(int arg), "text-scrolled") +_WRAP_SIGNAL(void window_title_changed(), "window-title-changed") + char* get_text(const SlotIsSelected& slot, std::vector<CharAttributes>& attributes); + char* get_text_include_trailing_spaces(const SlotIsSelected& slot, std::vector<CharAttributes>& attributes); + char* get_text_range(long start_row, long start_col, long end_row, long end_col, const SlotIsSelected& slot, std::vector<CharAttributes>& attributes); +}; + +} /* namespace Vte */ diff --git a/0.8.0/src/paludis/Makefile.am b/0.8.0/src/paludis/Makefile.am new file mode 100644 index 000000000..4185f8841 --- /dev/null +++ b/0.8.0/src/paludis/Makefile.am @@ -0,0 +1,76 @@ +AM_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src @PALUDIS_CXXFLAGS@ +DEFS= \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DDATADIR=\"$(datadir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DLIBDIR=\"$(libdir)\" + +SUBDIRS = . + +bin_PROGRAMS = paludis +noinst_PROGRAMS = man-paludis + +man_MANS = paludis.1 + +paludis.1 : man-paludis + ./man-paludis | tee $@ | sed -e 's/^/ /' + +man_paludis_SOURCES = \ + man_paludis.cc \ + command_line.hh \ + command_line.cc + +man_paludis_LDADD = \ + $(top_builddir)/paludis/args/libpaludisargs.la \ + $(top_builddir)/paludis/util/libpaludisutil.la \ + $(top_builddir)/src/libcolour.a \ + $(DYNAMIC_LD_LIBS) + +paludis_SOURCES = \ + applets.hh applets.cc \ + command_line.hh command_line.cc \ + install.hh install.cc \ + uninstall.hh uninstall.cc \ + list.hh list.cc \ + query.hh query.cc \ + sync.hh sync.cc \ + licence.hh licence.cc \ + use.hh use.cc \ + contents.hh contents.cc \ + owner.hh owner.cc \ + news.hh news.cc \ + paludis.cc + +paludis_LDADD = \ + $(top_builddir)/paludis/tasks/libpaludistasks.a \ + $(top_builddir)/paludis/libpaludis.la \ + $(top_builddir)/paludis/args/libpaludisargs.la \ + $(top_builddir)/paludis/util/libpaludisutil.la \ + $(top_builddir)/paludis/environment/default/libpaludisdefaultenvironment.la \ + $(top_builddir)/src/libcolour.a \ + $(DYNAMIC_LD_LIBS) + +TESTS_ENVIRONMENT = env \ + TEST_SCRIPT_DIR="$(srcdir)/" \ + PALUDIS_NO_GLOBAL_HOOKS="yes" \ + PALUDIS_NO_XTERM_TITLES="yes" \ + PALUDIS_EBUILD_DIR="`$(top_srcdir)/ebuild/utils/canonicalise $(top_srcdir)/ebuild/`" \ + PALUDIS_EBUILD_DIR_FALLBACK="`$(top_srcdir)/ebuild/utils/canonicalise $(top_builddir)/ebuild/`" \ + PALUDIS_REPOSITORY_SO_DIR="`$(top_srcdir)/ebuild/utils/canonicalise $(top_builddir)/paludis/repositories`" \ + SYSCONFDIR="$(sysconfdir)" \ + bash $(top_srcdir)/test/run_test.sh bash + +TESTS = version_TEST help_TEST list_sync_formats_TEST \ + list_repository_formats_TEST list_dep_tag_categories_TEST \ + exception_TEST install_TEST upgrade_TEST + +EXTRA_DIST = \ + $(man_MANS) \ + $(TESTS) \ + install_TEST_setup.sh install_TEST_cleanup.sh \ + upgrade_TEST_setup.sh upgrade_TEST_cleanup.sh + +CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda +DISTCLEANFILES = $(man_MANS) +MAINTAINERCLEANFILES = Makefile.in + diff --git a/0.8.0/src/paludis/applets.cc b/0.8.0/src/paludis/applets.cc new file mode 100644 index 000000000..43d8f00d9 --- /dev/null +++ b/0.8.0/src/paludis/applets.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 "applets.hh" +#include "colour.hh" +#include <functional> +#include <iomanip> +#include <iostream> +#include <paludis/paludis.hh> +#include <paludis/environment/default/default_environment.hh> +#include <string> +#include <set> + +/** \file + * Handle the --has-version, --best-version and various --list actions for the + * main paludis program. + */ + +namespace p = paludis; + +int do_has_version() +{ + int return_code(0); + + p::Context context("When performing has-version action from command line:"); + p::Environment * const env(p::DefaultEnvironment::get_instance()); + + std::string query(*CommandLine::get_instance()->begin_parameters()); + p::PackageDepAtom::Pointer atom(new p::PackageDepAtom(query)); + p::PackageDatabaseEntryCollection::ConstPointer entries(env->package_database()->query( + atom, p::is_installed_only)); + if (entries->empty()) + return_code = 1; + + return return_code; +} + +int do_best_version() +{ + int return_code(0); + + p::Context context("When performing best-version action from command line:"); + p::Environment * const env(p::DefaultEnvironment::get_instance()); + + std::string query(*CommandLine::get_instance()->begin_parameters()); + p::PackageDepAtom::Pointer atom(new p::PackageDepAtom(query)); + p::PackageDatabaseEntryCollection::ConstPointer entries(env->package_database()->query( + atom, p::is_installed_only)); + if (entries->empty()) + return_code = 1; + else + { + // don't include repo, it breaks built_with_use and the like. + std::string entry( + stringify(entries->last()->name) + "-" + + stringify(entries->last()->version)); + std::cout << entry << std::endl; + } + + return return_code; +} + +int do_environment_variable() +{ + int return_code(0); + + p::Context context("When performing environment-variable action from command line:"); + p::Environment * const env(p::DefaultEnvironment::get_instance()); + + std::string atom_str(*CommandLine::get_instance()->begin_parameters()); + std::string var_str(* p::next(CommandLine::get_instance()->begin_parameters())); + p::PackageDepAtom::Pointer atom(new p::PackageDepAtom(atom_str)); + + p::PackageDatabaseEntryCollection::ConstPointer entries(env->package_database()->query( + atom, p::is_installed_only)); + + if (entries->empty()) + entries = env->package_database()->query(atom, p::is_uninstalled_only); + + if (entries->empty()) + throw p::NoSuchPackageError(atom_str); + + p::Repository::ConstPointer repo(env->package_database()->fetch_repository( + entries->begin()->repository)); + p::RepositoryEnvironmentVariableInterface * env_if( + repo->environment_variable_interface); + + if (! env_if) + { + std::cerr << "Repository '" << repo->name() << + "' cannot be queried for environment variables" << std::endl; + return_code |= 1; + } + else + std::cout << env_if->get_environment_variable(*entries->begin(), var_str) << std::endl; + + return return_code; +} + +int do_configuration_variable() +{ + int return_code(0); + + p::Context context("When performing configuration-variable action from command line:"); + p::Environment * const env(p::DefaultEnvironment::get_instance()); + + std::string repo_str(*CommandLine::get_instance()->begin_parameters()); + std::string var_str(* p::next(CommandLine::get_instance()->begin_parameters())); + + p::RepositoryInfo::ConstPointer info(env->package_database()->fetch_repository( + p::RepositoryName(repo_str))->info(false)); + + return_code = 1; + for (p::RepositoryInfo::SectionIterator s(info->begin_sections()), + s_end(info->end_sections()) ; s != s_end ; ++s) + for (p::RepositoryInfoSection::KeyValueIterator k((*s)->begin_kvs()), + k_end((*s)->end_kvs()) ; k != k_end ; ++k) + if (var_str == k->first) + { + std::cout << k->second << std::endl; + return_code = 0; + break; + } + + return return_code; +} + +int do_list_repository_formats() +{ + int return_code(1); + + std::set<std::string> keys; + p::RepositoryMaker::get_instance()->copy_keys(std::inserter(keys, keys.begin())); + + if (! keys.empty()) + { + return_code = 0; + for (std::set<std::string>::const_iterator k(keys.begin()), k_end(keys.end()) ; + k != k_end ; ++k) + std::cout << "* " << colour(cl_key_name, *k) << std::endl; + } + + return return_code; +} + +int do_list_sync_protocols() +{ + int return_code(1); + + std::set<std::string> keys; + p::SyncerMaker::get_instance()->copy_keys(std::inserter(keys, keys.begin())); + + if (! keys.empty()) + { + return_code = 0; + for (std::set<std::string>::const_iterator k(keys.begin()), k_end(keys.end()) ; + k != k_end ; ++k) + std::cout << "* " << colour(cl_key_name, *k) << std::endl; + } + + return return_code; +} + +int do_list_dep_tag_categories() +{ + int return_code(1); + + std::set<std::string> keys; + p::DepTagCategoryMaker::get_instance()->copy_keys(std::inserter(keys, keys.begin())); + + if (! keys.empty()) + { + return_code = 0; + for (std::set<std::string>::const_iterator k(keys.begin()), k_end(keys.end()) ; + k != k_end ; ++k) + std::cout << "* " << colour(cl_key_name, *k) << std::endl; + } + + return return_code; +} + diff --git a/0.8.0/src/paludis/applets.hh b/0.8.0/src/paludis/applets.hh new file mode 100644 index 000000000..108b962a7 --- /dev/null +++ b/0.8.0/src/paludis/applets.hh @@ -0,0 +1,51 @@ +/* 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_SRC_APPLETS_HH +#define PALUDIS_GUARD_SRC_APPLETS_HH 1 + +#include "command_line.hh" + +/** \file + * Declaration for small do_* functions. + */ + +/// Handle --has-version. +int do_has_version(); + +/// Handle --best-version. +int do_best_version(); + +/// Handle --environment-variable. +int do_environment_variable(); + +/// Handle --configuration-variable. +int do_configuration_variable(); + +/// Handle --list-repository-formats +int do_list_repository_formats(); + +/// Handle --list-sync-protocols +int do_list_sync_protocols(); + +/// Handle --list-dep-tag-categories +int do_list_dep_tag_categories(); + +#endif + diff --git a/0.8.0/src/paludis/command_line.cc b/0.8.0/src/paludis/command_line.cc new file mode 100644 index 000000000..a3b10c0f4 --- /dev/null +++ b/0.8.0/src/paludis/command_line.cc @@ -0,0 +1,227 @@ +/* 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 "command_line.hh" + +CommandLine::CommandLine() : + ArgsHandler(), + + action_args(this, "Actions", + "Selects which basic action to perform. Exactly one action should " + "be specified."), + a_query(&action_args, "query", 'q', "Query for package information"), + a_install(&action_args, "install", 'i', "Install one or more packages"), + a_uninstall(&action_args, "uninstall", 'u', "Uninstall one or more packages"), + a_sync(&action_args, "sync", 's', "Sync all or specified repositories"), + a_contents(&action_args, "contents", 'k', "Display contents of a package"), + a_owner(&action_args, "owner", 'o', "Display the owner of a file"), + a_version(&action_args, "version", 'V', "Display program version"), + a_info(&action_args, "info", 'I', "Display program version and system information"), + a_help(&action_args, "help", 'h', "Display program help"), + + action_args_internal(this, "More actions", + "Additional actions, mostly for script and internal use."), + a_has_version(&action_args_internal, "has-version", '\0', "Check whether the specified atom is installed"), + a_best_version(&action_args_internal, "best-version", '\0', "Display the best version of the specified atom"), + a_environment_variable(&action_args_internal, "environment-variable", '\0', "Display the value of an environment " + "variable for a particular package"), + a_configuration_variable(&action_args_internal, "configuration-variable", '\0', "Display the value of a " + "configuration variable for a particular repository"), + a_list_repositories(&action_args_internal, "list-repositories", '\0', "List available repositories"), + a_list_categories(&action_args_internal, "list-categories", '\0', "List available categories"), + a_list_packages(&action_args_internal, "list-packages", '\0', "List available packages"), + a_list_sets(&action_args_internal, "list-sets", '\0', "List available package sets"), + a_list_sync_protocols(&action_args_internal, "list-sync-protocols", '\0', "List available sync protocols"), + a_list_repository_formats(&action_args_internal, "list-repository-formats", '\0', + "List available repository formats"), + a_list_dep_tag_categories(&action_args_internal, "list-dep-tag-categories", '\0', "List known dep tag categories"), + a_update_news(&action_args_internal, "update-news", '\0', "Regenerate news.unread files"), + + general_args(this, "General options", + "Options which are relevant for most or all actions."), + a_log_level(&general_args, "log-level", '\0', "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"), + "qa"), + a_no_colour(&general_args, "no-colour", '\0', "Do not use colour"), + a_no_color(&a_no_colour, "no-color"), + a_config_suffix(&general_args, "config-suffix", 'c', "Config directory suffix"), + + query_args(this, "Query options", + "Options which are relevant for --query."), + a_show_slot(&query_args, "show-slot", 'S', "Show SLOTs"), + a_show_deps(&query_args, "show-deps", 'D', "Show dependencies"), + a_show_metadata(&query_args, "show-metadata", 'M', "Show raw metadata"), + + install_args(this, "Install, Uninstall options", + "Options which are relevant for --install or --uninstall."), + a_pretend(&install_args, "pretend", 'p', "Pretend only"), + a_preserve_world(&install_args, "preserve-world", '1', "Don't modify the world file"), + a_no_config_protection(&install_args, "no-config-protection", '\0', "Disable config file protection (dangerous)"), + a_fetch(&install_args, "fetch", 'f', "Only fetch sources; don't install anything"), + a_show_install_reasons(&install_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"), + + dl_args(this, "DepList behaviour", + "Modify dependency list generation behaviour. Use with caution."), + + dl_reinstall(&dl_args, "dl-reinstall", '\0', "When to reinstall packages", + paludis::args::EnumArg::EnumArgOptions + ("never", "Never") + ("always", "Always") + ("if-use-changed", "If USE flags have changed"), + "never"), + dl_upgrade(&dl_args, "dl-upgrade", '\0', "When to upgrade packages", + paludis::args::EnumArg::EnumArgOptions + ("always", "Always") + ("as-needed", "As needed"), + "always"), + + dl_installed_deps_pre(&dl_args, "dl-installed-deps-pre", '\0', "How to handle pre dependencies for installed packages", + paludis::args::EnumArg::EnumArgOptions + ("pre", "As pre dependencies") + ("pre-or-post", "As pre dependencies, or post depenencies where needed") + ("post", "As post dependencies") + ("try-post", "As post dependencies, with no error for failures") + ("discard", "Discard"), + "discard"), + dl_installed_deps_runtime(&dl_args, "dl-installed-deps-runtime", '\0', "How to handle runtime dependencies for installed packages", + paludis::args::EnumArg::EnumArgOptions + ("pre", "As pre dependencies") + ("pre-or-post", "As pre dependencies, or post depenencies where needed") + ("post", "As post dependencies") + ("try-post", "As post dependencies, with no error for failures") + ("discard", "Discard"), + "try-post"), + dl_installed_deps_post(&dl_args, "dl-installed-deps-post", '\0', "How to handle post dependencies for installed packages", + paludis::args::EnumArg::EnumArgOptions + ("pre", "As pre dependencies") + ("pre-or-post", "As pre dependencies, or post depenencies where needed") + ("post", "As post dependencies") + ("try-post", "As post dependencies, with no error for failures") + ("discard", "Discard"), + "try-post"), + + dl_uninstalled_deps_pre(&dl_args, "dl-uninstalled-deps-pre", '\0', "How to handle pre dependencies for uninstalled packages", + paludis::args::EnumArg::EnumArgOptions + ("pre", "As pre dependencies") + ("pre-or-post", "As pre dependencies, or post depenencies where needed") + ("post", "As post dependencies") + ("try-post", "As post dependencies, with no error for failures") + ("discard", "Discard"), + "pre"), + dl_uninstalled_deps_runtime(&dl_args, "dl-uninstalled-deps-runtime", '\0', "How to handle runtime dependencies for uninstalled packages", + paludis::args::EnumArg::EnumArgOptions + ("pre", "As pre dependencies") + ("pre-or-post", "As pre dependencies, or post depenencies where needed") + ("post", "As post dependencies") + ("try-post", "As post dependencies, with no error for failures") + ("discard", "Discard"), + "pre-or-post"), + dl_uninstalled_deps_post(&dl_args, "dl-uninstalled-deps-post", '\0', "How to handle post dependencies for uninstalled packages", + paludis::args::EnumArg::EnumArgOptions + ("pre", "As pre dependencies") + ("pre-or-post", "As pre dependencies, or post depenencies where needed") + ("post", "As post dependencies") + ("try-post", "As post dependencies, with no error for failures") + ("discard", "Discard"), + "post"), + + dl_circular(&dl_args, "dl-circular", '\0', "How to handle circular dependencies", + paludis::args::EnumArg::EnumArgOptions + ("error", "Raise an error") + ("discard", "Discard"), + "error"), + + list_args(this, "List options", + "Options relevant for one or more of the --list actions."), + a_repository(&list_args, "repository", '\0', "Matches with this repository name only"), + a_category(&list_args, "category", '\0', "Matches with this category name only"), + a_package(&list_args, "package", '\0', "Matches with this package name only"), + a_set(&list_args, "set", '\0', "Matches with this package set name only"), + + owner_args(this, "Owner options", + "Options relevant for the --owner actions."), + a_full_match(&owner_args, "full-match", '\0', "Match whole filename") +{ + add_usage_line("--query [query options] target ..."); + add_usage_line("--install [install options] target ..."); + add_usage_line("--sync [target (leave blank for all)]"); + add_usage_line("--contents target ..."); + add_usage_line("--owner [owner options] files ..."); + add_usage_line("--version"); + add_usage_line("--info"); + add_usage_line("--help"); + + add_usage_line("--has-version atom"); + add_usage_line("--best-version atom"); + add_usage_line("--environment-variable atom variable"); + add_usage_line("--configuration-variable repository variable"); + add_usage_line("--list-repositories [--repository repo1 --repository repo2 ...]"); + add_usage_line("--list-categories [--repository repo1 ... --category cat1 --category cat2 ...]"); + add_usage_line("--list-packages [--repository repo1 ... --category cat1 ... --package pkg1 --package pkg2 ...]"); + add_usage_line("--list-sets [--repository repo1 ... --set set1 ...]"); + add_usage_line("--list-sync-protocols"); + add_usage_line("--list-repository-formats"); + add_usage_line("--list-dep-tag-categories"); + add_usage_line("--update-news"); + + add_enviromnent_variable("PALUDIS_HOME", "Overrides the home directory used when searching " + "for configuration files etc."); + add_enviromnent_variable("PALUDIS_NO_GLOBAL_HOOKS", "Don't use global hooks. Mostly for " + "internal and test case use."); + add_enviromnent_variable("PALUDIS_SKIP_CONFIG", "Don't load configuration. Mostly for " + "internal and test case use."); + add_enviromnent_variable("PALUDIS_EBUILD_DIR", "Where to look for ebuild.bash and related " + "utilities."); + add_enviromnent_variable("PALUDIS_REPOSITORY_SO_DIR", "Where to look for repository .so " + "files."); +} + +std::string +CommandLine::app_name() const +{ + return "paludis"; +} + +std::string +CommandLine::app_synopsis() const +{ + return "The other package mangler"; +} + +std::string +CommandLine::app_description() const +{ + return + "paludis is the command line interface used to handle packages. It can query and " + "install packages, update repositories and display information about packages " + "already installed on a system."; +} + +CommandLine::~CommandLine() +{ +} + diff --git a/0.8.0/src/paludis/command_line.hh b/0.8.0/src/paludis/command_line.hh new file mode 100644 index 000000000..bd60b6ce5 --- /dev/null +++ b/0.8.0/src/paludis/command_line.hh @@ -0,0 +1,256 @@ +/* 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_SRC_COMMAND_LINE_HH +#define PALUDIS_GUARD_SRC_COMMAND_LINE_HH 1 + +#include <paludis/args/args.hh> +#include <paludis/util/instantiation_policy.hh> + +/** \file + * Declarations for the CommandLine class. + */ + +/** + * Our command line. + */ +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; + + /// --query + paludis::args::SwitchArg a_query; + + /// --install + paludis::args::SwitchArg a_install; + + /// --uninstall + paludis::args::SwitchArg a_uninstall; + + /// --sync + paludis::args::SwitchArg a_sync; + + /// --contents + paludis::args::SwitchArg a_contents; + + /// --owner + paludis::args::SwitchArg a_owner; + + /// --version + paludis::args::SwitchArg a_version; + + /// --info + paludis::args::SwitchArg a_info; + + /// --help + paludis::args::SwitchArg a_help; + + /// Action arguments (internal). + paludis::args::ArgsGroup action_args_internal; + + /// --has-version + paludis::args::SwitchArg a_has_version; + + /// --best-version + paludis::args::SwitchArg a_best_version; + + /// --environment-variable + paludis::args::SwitchArg a_environment_variable; + + /// --configuration-variable + paludis::args::SwitchArg a_configuration_variable; + + /// --list-repositories + paludis::args::SwitchArg a_list_repositories; + + /// --list-categories + paludis::args::SwitchArg a_list_categories; + + /// --list-packages + paludis::args::SwitchArg a_list_packages; + + /// --list-sets + paludis::args::SwitchArg a_list_sets; + + /// --list-sync-protocols + paludis::args::SwitchArg a_list_sync_protocols; + + /// --list-repository-formats + paludis::args::SwitchArg a_list_repository_formats; + + /// --list-dep-tag-categories + paludis::args::SwitchArg a_list_dep_tag_categories; + + /// --update-news + paludis::args::SwitchArg a_update_news; + + ///} + + /// \name General arguments + ///{ + + /// General arguments. + paludis::args::ArgsGroup general_args; + + /// --log-level + paludis::args::EnumArg a_log_level; + + /// --no-colour + paludis::args::SwitchArg a_no_colour; + + /// --no-color + paludis::args::AliasArg a_no_color; + + /// --config-suffix + paludis::args::StringArg a_config_suffix; + + ///} + + /// \name Query arguments + ///{ + + /// Query arguments. + paludis::args::ArgsGroup query_args; + + /// --show-slot + paludis::args::SwitchArg a_show_slot; + + /// --show-deps + paludis::args::SwitchArg a_show_deps; + + /// --show-metadata + paludis::args::SwitchArg a_show_metadata; + + /// } + + /// \name (Un)Install arguments + /// { + + /// Install arguments. + paludis::args::ArgsGroup install_args; + + /// --pretend + paludis::args::SwitchArg a_pretend; + + /// --preserve-world + paludis::args::SwitchArg a_preserve_world; + + /// --no-config-protection + paludis::args::SwitchArg a_no_config_protection; + + /// --fetch + paludis::args::SwitchArg a_fetch; + + /// --show-install-reasons + paludis::args::EnumArg a_show_install_reasons; + + /// } + + /// \name DepList behaviour arguments + /// { + + /// DepList behaviour arguments. + paludis::args::ArgsGroup dl_args; + + paludis::args::EnumArg dl_reinstall; + paludis::args::EnumArg dl_upgrade; + + paludis::args::EnumArg dl_installed_deps_pre; + paludis::args::EnumArg dl_installed_deps_runtime; + paludis::args::EnumArg dl_installed_deps_post; + + paludis::args::EnumArg dl_uninstalled_deps_pre; + paludis::args::EnumArg dl_uninstalled_deps_runtime; + paludis::args::EnumArg dl_uninstalled_deps_post; + + paludis::args::EnumArg dl_circular; + + /// } + + /// \name List arguments + /// { + + /// List arguments. + paludis::args::ArgsGroup list_args; + + /// --repository + paludis::args::StringSetArg a_repository; + + /// --category + paludis::args::StringSetArg a_category; + + /// --package + paludis::args::StringSetArg a_package; + + /// --set + paludis::args::StringSetArg a_set; + + /// } + + /// \name Owner arguments + /// { + + /// Owner arguments. + paludis::args::ArgsGroup owner_args; + + /// --full-match + paludis::args::SwitchArg a_full_match; + + /// } +}; + +/** + * Show the help message. + */ +struct DoHelp +{ + const std::string message; + + DoHelp(const std::string & m = "") : + message(m) + { + } +}; + +#endif diff --git a/0.8.0/src/paludis/contents.cc b/0.8.0/src/paludis/contents.cc new file mode 100644 index 000000000..ca9efc009 --- /dev/null +++ b/0.8.0/src/paludis/contents.cc @@ -0,0 +1,155 @@ +/* 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 "contents.hh" +#include "colour.hh" +#include "command_line.hh" +#include <paludis/paludis.hh> +#include <paludis/environment/default/default_environment.hh> +#include <iostream> +#include <algorithm> + +namespace p = paludis; +using std::cout; +using std::cerr; +using std::endl; + +namespace +{ + struct ContentsDisplayer : + p::ContentsVisitorTypes::ConstVisitor + { + void visit(const p::ContentsFileEntry * const e) + { + cout << " " << colour(cl_file, e->name()) << endl; + } + + void visit(const p::ContentsDirEntry * const e) + { + cout << " " << colour(cl_dir, e->name()) << endl; + } + + void visit(const p::ContentsSymEntry * const e) + { + cout << " " << colour(cl_sym, e->name()) << " -> " << e->target() << endl; + } + + void visit(const p::ContentsMiscEntry * const e) + { + cout << " " << colour(cl_misc, e->name()) << endl; + } + }; +} + +void +do_one_contents_entry( + const p::Environment * const env, + const p::PackageDatabaseEntry & e) +{ + cout << "* " << colour(cl_package_name, e) << endl; + + const p::RepositoryInstalledInterface * const installed_interface( + env->package_database()->fetch_repository(e.repository)-> + installed_interface); + if (installed_interface) + { + p::Contents::ConstPointer contents(installed_interface->contents( + e.name, e.version)); + ContentsDisplayer d; + std::for_each(contents->begin(), contents->end(), accept_visitor(&d)); + } + else + cout << " " << colour(cl_error, "(unknown)") << endl; + + cout << endl; +} + +void +do_one_contents( + const p::Environment * const env, + const std::string & q) +{ + p::Context local_context("When handling query '" + q + "':"); + + /* we might have a dep atom, but we might just have a simple package name + * without a category. either should work. */ + p::PackageDepAtom::Pointer atom(std::string::npos == q.find('/') ? + new p::PackageDepAtom(env->package_database()->fetch_unique_qualified_package_name( + p::PackageNamePart(q))) : + new p::PackageDepAtom(q)); + + p::PackageDatabaseEntryCollection::ConstPointer + entries(env->package_database()->query(atom, p::is_installed_only)); + + if (entries->empty()) + throw p::NoSuchPackageError(q); + + for (p::PackageDatabaseEntryCollection::Iterator i(entries->begin()), + i_end(entries->end()) ; i != i_end ; ++i) + do_one_contents_entry(env, *i); +} + +int +do_contents() +{ + int return_code(0); + + p::Context context("When performing contents action from command line:"); + p::Environment * const env(p::DefaultEnvironment::get_instance()); + + CommandLine::ParametersIterator q(CommandLine::get_instance()->begin_parameters()), + q_end(CommandLine::get_instance()->end_parameters()); + for ( ; q != q_end ; ++q) + { + try + { + do_one_contents(env, *q); + } + catch (const p::AmbiguousPackageNameError & e) + { + cout << endl; + cerr << "Query error:" << endl; + cerr << " * " << e.backtrace("\n * "); + cerr << "Ambiguous package name '" << e.name() << "'. Did you mean:" << endl; + for (p::AmbiguousPackageNameError::OptionsIterator o(e.begin_options()), + o_end(e.end_options()) ; o != o_end ; ++o) + cerr << " * " << colour(cl_package_name, *o) << endl; + cerr << endl; + } + catch (const p::NameError & e) + { + return_code |= 1; + cout << endl; + cerr << "Query error:" << endl; + cerr << " * " << e.backtrace("\n * ") << e.message() << endl; + cerr << endl; + } + catch (const p::PackageDatabaseLookupError & e) + { + return_code |= 1; + cout << endl; + cerr << "Query error:" << endl; + cerr << " * " << e.backtrace("\n * ") << e.message() << endl; + cerr << endl; + } + } + + return return_code; +} + diff --git a/0.8.0/src/paludis/contents.hh b/0.8.0/src/paludis/contents.hh new file mode 100644 index 000000000..5cf38e3b7 --- /dev/null +++ b/0.8.0/src/paludis/contents.hh @@ -0,0 +1,30 @@ +/* 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_SRC_CONTENTS_HH +#define PALUDIS_GUARD_SRC_CONTENTS_HH 1 + +/** \file + * Declaration for the do_contents function. + */ + +/// Handle --contents. +int do_contents(); + +#endif diff --git a/0.8.0/src/paludis/exception_TEST b/0.8.0/src/paludis/exception_TEST new file mode 100755 index 000000000..a3daaaf26 --- /dev/null +++ b/0.8.0/src/paludis/exception_TEST @@ -0,0 +1,6 @@ +#!/bin/bash + +PALUDIS_HOME=./ \ + ./paludis --config-suffix paludis-build-test -pi asdf 2>&1 \ + | grep 'Default configuration error' >/dev/null + diff --git a/0.8.0/src/paludis/help_TEST b/0.8.0/src/paludis/help_TEST new file mode 100755 index 000000000..3a0f5fbb5 --- /dev/null +++ b/0.8.0/src/paludis/help_TEST @@ -0,0 +1,3 @@ +#!/bin/bash + +PALUDIS_SKIP_CONFIG=yes ./paludis --help diff --git a/0.8.0/src/paludis/install.cc b/0.8.0/src/paludis/install.cc new file mode 100644 index 000000000..5de8260a4 --- /dev/null +++ b/0.8.0/src/paludis/install.cc @@ -0,0 +1,915 @@ +/* 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 "colour.hh" +#include "install.hh" +#include "licence.hh" +#include "use.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/log.hh> +#include <paludis/util/tokeniser.hh> +#include <paludis/environment/default/default_environment.hh> + +/** \file + * Handle the --install action for the main paludis program. + */ + +using namespace paludis; + +using std::cerr; +using std::cout; +using std::endl; + +namespace +{ + struct TagDisplayer : + DepTagVisitorTypes::ConstVisitor + { + void visit(const GLSADepTag * const tag) + { + cout << "* " << colour(cl_tag, tag->short_text()) << ": " + << tag->glsa_title() << endl; + } + + void visit(const DependencyDepTag * const) + { + } + + void visit(const GeneralSetDepTag * const tag) + { + cout << "* " << colour(cl_tag, tag->short_text()); + if (tag->short_text() == "world") + cout << ": " << "Packages that have been explicitly installed"; + else if (tag->short_text() == "everything") + cout << ": " << "All installed packages"; + else if (tag->short_text() == "system") + cout << ": " << "Packages that are part of the base system"; + cout << endl; + } + }; + + class OurInstallTask : + public InstallTask + { + private: + int _current_count, _max_count, _new_count, _upgrade_count, + _downgrade_count, _new_slot_count, _rebuild_count, + _current_virtual_count, _max_virtual_count, _new_virtual_count, + _upgrade_virtual_count, _downgrade_virtual_count, + _new_slot_virtual_count, _rebuild_virtual_count; + + std::set<DepTagEntry> _all_tags; + + public: + OurInstallTask(const DepListOptions & options) : + InstallTask(DefaultEnvironment::get_instance(), options), + _current_count(0), + _max_count(0), + _new_count(0), + _upgrade_count(0), + _downgrade_count(0), + _new_slot_count(0), + _rebuild_count(0), + _current_virtual_count(0), + _max_virtual_count(0), + _new_virtual_count(0), + _upgrade_virtual_count(0), + _downgrade_virtual_count(0), + _new_slot_virtual_count(0), + _rebuild_virtual_count(0) + { + } + + void on_build_deplist_pre() + { + cout << "Building dependency list... " << std::flush; + } + + virtual void on_build_deplist_post() + { + cout << "done" << endl; + } + + virtual void on_build_cleanlist_pre(const DepListEntry & d) + { + cout << endl << colour(cl_heading, "Cleaning stale versions after installing " + + stringify(d.package.name) + "-" + stringify(d.package.version) + + "::" + stringify(d.package.repository)) << endl << endl; + } + + virtual void on_build_cleanlist_post(const DepListEntry &) + { + } + + virtual void on_clean_all_pre(const DepListEntry &, + const PackageDatabaseEntryCollection & c) + { + if (c.empty()) + cout << "* No cleaning required" << endl; + else + { + for (PackageDatabaseEntryCollection::Iterator cc(c.begin()), + cc_end(c.end()) ; cc != cc_end ; ++cc) + cout << "* " << colour(cl_package_name, *cc) << endl; + } + cout << endl; + } + + virtual void on_clean_pre(const DepListEntry &, + const PackageDatabaseEntry & c) + { + cout << colour(cl_heading, "Cleaning " + stringify(c)) << endl << endl; + + cerr << xterm_title("(" + stringify(_current_count) + " of " + + stringify(_max_count + _max_virtual_count) + ") Cleaning " + stringify(c)); + } + + virtual void on_clean_post(const DepListEntry &, + const PackageDatabaseEntry &) + { + } + + virtual void on_clean_all_post(const DepListEntry &, + const PackageDatabaseEntryCollection &) + { + } + + virtual void on_display_merge_list_pre() + { + cout << endl << colour(cl_heading, "These packages will be installed:") + << endl << endl; + } + + virtual void on_display_merge_list_post(); + virtual void on_display_merge_list_entry(const DepListEntry &); + + virtual void on_fetch_all_pre() + { + } + + virtual void on_fetch_pre(const DepListEntry & d) + { + cout << colour(cl_heading, "Fetching " + + stringify(d.package.name) + "-" + stringify(d.package.version) + + "::" + stringify(d.package.repository)) << endl << endl; + + cerr << xterm_title("(" + stringify(++_current_count) + " of " + + stringify(_max_count + _max_virtual_count) + ") Fetching " + + stringify(d.package.name) + "-" + stringify(d.package.version) + + "::" + stringify(d.package.repository)); + } + + virtual void on_fetch_post(const DepListEntry &) + { + } + + virtual void on_fetch_all_post() + { + } + + virtual void on_install_all_pre() + { + } + + virtual void on_install_pre(const DepListEntry & d) + { + cout << endl << colour(cl_heading, "Installing " + + stringify(d.package.name) + "-" + stringify(d.package.version) + + "::" + stringify(d.package.repository)) << endl << endl; + + cerr << xterm_title("(" + stringify(++_current_count) + " of " + + stringify(_max_count + _max_virtual_count) + ") Installing " + + stringify(d.package.name) + "-" + stringify(d.package.version) + + "::" + stringify(d.package.repository)); + } + + virtual void on_install_post(const DepListEntry &) + { + } + + virtual void on_install_all_post() + { + } + + virtual void on_update_world_pre() + { + cout << endl << colour(cl_heading, "Updating world file") << endl << endl; + } + + virtual void on_update_world(const PackageDepAtom & a) + { + cout << "* adding " << colour(cl_package_name, a.package()) << endl; + } + + virtual void on_update_world_skip(const PackageDepAtom & a, const std::string & s) + { + cout << "* skipping " << colour(cl_package_name, a.package()) << " (" + << s << ")" << endl; + } + + virtual void on_update_world_post() + { + cout << endl; + } + + virtual void on_preserve_world() + { + cout << endl << colour(cl_heading, "Updating world file") << endl << endl; + cout << "* --preserve-world was specified, skipping world changes" << endl; + cout << endl; + } + }; + + void + OurInstallTask::on_display_merge_list_post() + { + if (_max_count != _new_count + _upgrade_count + _downgrade_count + _new_slot_count + + _rebuild_count) + Log::get_instance()->message(ll_warning, lc_no_context, + "Max count doesn't add up. This is a bug!"); + + if (_max_virtual_count != _new_virtual_count + _upgrade_virtual_count + + _downgrade_virtual_count + _new_slot_virtual_count + _rebuild_virtual_count) + Log::get_instance()->message(ll_warning, lc_no_context, + "Max virtuals count doesn't add up. This is a bug!"); + + cout << endl << "Total: " << _max_count << (_max_count == 1 ? " package" : " packages"); + if (_max_count) + { + bool need_comma(false); + cout << " ("; + if (_new_count) + { + cout << _new_count << " new"; + need_comma = true; + } + if (_upgrade_count) + { + if (need_comma) + cout << ", "; + cout << _upgrade_count << (_upgrade_count == 1 ? " upgrade" : " upgrades"); + need_comma = true; + } + if (_downgrade_count) + { + if (need_comma) + cout << ", "; + cout << _downgrade_count << (_downgrade_count == 1 ? " downgrade" : " downgrades"); + need_comma = true; + } + if (_new_slot_count) + { + if (need_comma) + cout << ", "; + cout << _new_slot_count << (_new_slot_count == 1 ? " in new slot" : " in new slots"); + need_comma = true; + } + if (_rebuild_count) + { + if (need_comma) + cout << ", "; + cout << _rebuild_count << (_rebuild_count == 1 ? " rebuild" : " rebuilds"); + need_comma = true; + } + cout << ")"; + } + + if (_max_virtual_count) + { + cout << " and " << _max_virtual_count << (_max_virtual_count == 1 + ? " virtual" : " virtuals"); + bool need_comma(false); + cout << " ("; + if (_new_virtual_count) + { + cout << _new_virtual_count << " new"; + need_comma = true; + } + if (_upgrade_virtual_count) + { + if (need_comma) + cout << ", "; + cout << _upgrade_virtual_count << (_upgrade_virtual_count == 1 ? " upgrade" : " upgrades"); + need_comma = true; + } + if (_downgrade_virtual_count) + { + if (need_comma) + cout << ", "; + cout << _downgrade_virtual_count << (_downgrade_virtual_count == 1 ? + " downgrade" : " downgrades"); + need_comma = true; + } + if (_new_slot_virtual_count) + { + if (need_comma) + cout << ", "; + cout << _new_slot_virtual_count << (_new_slot_virtual_count == 1 ? + " in new slot" : " in new slots"); + need_comma = true; + } + if (_rebuild_virtual_count) + { + if (need_comma) + cout << ", "; + cout << _rebuild_virtual_count << (_rebuild_virtual_count == 1 ? + " rebuild" : " rebuilds"); + need_comma = true; + } + cout << ")"; + } + cout << endl << endl; + + if (CommandLine::get_instance()->a_pretend.specified() && ! _all_tags.empty()) + { + TagDisplayer tag_displayer; + + std::set<std::string> tag_categories; + for (std::set<DepTagEntry>::const_iterator a(_all_tags.begin()), + a_end(_all_tags.end()) ; a != a_end ; ++a) + tag_categories.insert(a->tag->category()); + + for (std::set<std::string>::iterator cat(tag_categories.begin()), + cat_end(tag_categories.end()) ; cat != cat_end ; ++cat) + { + DepTagCategory::ConstPointer c(DepTagCategoryMaker::get_instance()-> + find_maker(*cat)()); + + if (! c->visible()) + continue; + + if (! c->title().empty()) + cout << colour(cl_heading, c->title()) << ":" << endl << endl; + if (! c->pre_text().empty()) + cout << c->pre_text() << endl << endl; + + for (std::set<DepTagEntry>::const_iterator t(_all_tags.begin()), t_end(_all_tags.end()) ; + t != t_end ; ++t) + { + if (t->tag->category() != *cat) + continue; + t->tag->accept(&tag_displayer); + } + cout << endl; + + if (! c->post_text().empty()) + cout << c->post_text() << endl << endl; + } + } + } + + void + OurInstallTask::on_display_merge_list_entry(const DepListEntry & d) + { + if (d.already_installed && CommandLine::get_instance()->a_show_install_reasons.argument() != "full") + return; + + Context context("When displaying entry '" + stringify(d.package) + "':"); + + cout << "* " << colour(d.already_installed ? cl_unimportant : cl_package_name, + d.package.name); + + /* display version, unless it's 0 and our category is "virtual" */ + if ((VersionSpec("0") != d.package.version) || + CategoryNamePart("virtual") != d.package.name.category) + cout << "-" << d.package.version; + + /* display repository, unless it's our main repository */ + if (DefaultEnvironment::get_instance()->package_database()->favourite_repository() != + d.package.repository) + cout << "::" << d.package.repository; + + /* display slot name, unless it's 0 */ + if (SlotName("0") != d.metadata->slot) + cout << colour(d.already_installed ? cl_unimportant : cl_slot, + " {:" + stringify(d.metadata->slot) + "}"); + + /* indicate [U], [S], [N] or [-]. display existing version, if we're + * already installed */ + PackageDatabaseEntryCollection::Pointer existing(DefaultEnvironment::get_instance()->package_database()-> + query(PackageDepAtom::Pointer(new PackageDepAtom(stringify( + d.package.name))), is_installed_only)); + + if (d.already_installed) + cout << colour(cl_unimportant, " [-]"); + else if (existing->empty()) + { + cout << colour(cl_updatemode, " [N]"); + if (d.metadata->get_virtual_interface()) + { + ++_new_virtual_count; + ++_max_virtual_count; + } + else + { + ++_new_count; + ++_max_count; + } + } + else + { + existing = DefaultEnvironment::get_instance()->package_database()->query(PackageDepAtom::Pointer( + new PackageDepAtom(stringify(d.package.name) + ":" + + stringify(d.metadata->slot))), + is_installed_only); + if (existing->empty()) + { + cout << colour(cl_updatemode, " [S]"); + if (d.metadata->get_virtual_interface()) + { + ++_new_slot_virtual_count; + ++_max_virtual_count; + } + else + { + ++_new_slot_count; + ++_max_count; + } + } + else if (existing->last()->version < d.package.version) + { + cout << colour(cl_updatemode, " [U " + stringify( + existing->last()->version) + "]"); + if (d.metadata->get_virtual_interface()) + { + ++_upgrade_virtual_count; + ++_max_virtual_count; + } + else + { + ++_upgrade_count; + ++_max_count; + } + } + else if (existing->last()->version > d.package.version) + { + cout << colour(cl_updatemode, " [D " + stringify( + existing->last()->version) + "]"); + if (d.metadata->get_virtual_interface()) + { + ++_downgrade_virtual_count; + ++_max_virtual_count; + } + else + { + ++_downgrade_count; + ++_max_count; + } + + } + else + { + cout << colour(cl_updatemode, " [R]"); + if (d.metadata->get_virtual_interface()) + { + ++_rebuild_virtual_count; + ++_max_virtual_count; + } + else + { + ++_rebuild_count; + ++_max_count; + } + } + } + + /* fetch db entry */ + PackageDatabaseEntry p(d.package); + + /* display USE flags */ + if (! d.already_installed) + std::cout << make_pretty_use_flags_string(DefaultEnvironment::get_instance(), p, d.metadata, + (existing->empty() ? 0 : &*existing->last())); + + /* display tag, add tag to our post display list */ + if (! d.tags->empty()) + { + std::string tag_titles; + for (SortedCollection<DepTagEntry>::Iterator + tag(d.tags->begin()), + tag_end(d.tags->end()) ; + tag != tag_end ; ++tag) + { + if (tag->tag->category() == "dependency") + continue; + + _all_tags.insert(*tag); + tag_titles.append(tag->tag->short_text()); + tag_titles.append(", "); + } + if (! tag_titles.empty()) + { + tag_titles.erase(tag_titles.length() - 2); + cout << " " << colour(d.already_installed ? cl_unimportant : cl_tag, + "<" + tag_titles + ">"); + } + + /* display dependency tags */ + if ((CommandLine::get_instance()->a_show_install_reasons.argument() == "summary") || + (CommandLine::get_instance()->a_show_install_reasons.argument() == "full")) + { + std::string deps; + unsigned count(0), max_count; + if (CommandLine::get_instance()->a_show_install_reasons.argument() == "summary") + max_count = 3; + else + max_count = std::numeric_limits<long>::max(); + + for (SortedCollection<DepTagEntry>::Iterator + tag(d.tags->begin()), + tag_end(d.tags->end()) ; + tag != tag_end ; ++tag) + { + if (tag->tag->category() != "dependency") + continue; + + if (++count < max_count) + { + deps.append(tag->tag->short_text()); + deps.append(", "); + } + } + if (! deps.empty()) + { + if (count >= max_count) + deps.append(stringify(count - max_count + 1) + " more, "); + + deps.erase(deps.length() - 2); + cout << " " << colour(d.already_installed ? cl_unimportant : cl_tag, + "<" + deps + ">"); + } + } + } + + cout << endl; + } + + 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()) + { + cerr << "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->already_installed) + cerr << " =" << i->package.name << "-" << i->package.version << "::" << i->package.repository; + cerr << 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() +{ + int return_code(0); + + Context context("When performing install action from command line:"); + + DepListOptions options; + + if (CommandLine::get_instance()->dl_reinstall.specified()) + { + if (CommandLine::get_instance()->dl_reinstall.argument() == "never") + options.reinstall = dl_reinstall_never; + else if (CommandLine::get_instance()->dl_reinstall.argument() == "always") + options.reinstall = dl_reinstall_always; + else if (CommandLine::get_instance()->dl_reinstall.argument() == "if-use-changed") + options.reinstall = dl_reinstall_if_use_changed; + else + throw DoHelp("bad value for --dl-reinstall"); + } + + if (CommandLine::get_instance()->dl_upgrade.specified()) + { + if (CommandLine::get_instance()->dl_upgrade.argument() == "as-needed") + options.upgrade = dl_upgrade_as_needed; + else if (CommandLine::get_instance()->dl_upgrade.argument() == "always") + options.upgrade = dl_upgrade_always; + else + throw DoHelp("bad value for --dl-upgrade"); + } + + if (CommandLine::get_instance()->dl_circular.specified()) + { + if (CommandLine::get_instance()->dl_circular.argument() == "discard") + options.circular = dl_circular_discard; + else if (CommandLine::get_instance()->dl_circular.argument() == "error") + options.circular = dl_circular_error; + else + throw DoHelp("bad value for --dl-circular"); + } + + if (CommandLine::get_instance()->dl_installed_deps_pre.specified()) + options.installed_deps_pre = enum_arg_to_dep_list_deps_option( + CommandLine::get_instance()->dl_installed_deps_pre); + if (CommandLine::get_instance()->dl_installed_deps_runtime.specified()) + options.installed_deps_runtime = enum_arg_to_dep_list_deps_option( + CommandLine::get_instance()->dl_installed_deps_runtime); + if (CommandLine::get_instance()->dl_installed_deps_post.specified()) + options.installed_deps_post = enum_arg_to_dep_list_deps_option( + CommandLine::get_instance()->dl_installed_deps_post); + + if (CommandLine::get_instance()->dl_uninstalled_deps_pre.specified()) + options.uninstalled_deps_pre = enum_arg_to_dep_list_deps_option( + CommandLine::get_instance()->dl_uninstalled_deps_pre); + if (CommandLine::get_instance()->dl_uninstalled_deps_runtime.specified()) + options.uninstalled_deps_runtime = enum_arg_to_dep_list_deps_option( + CommandLine::get_instance()->dl_uninstalled_deps_runtime); + if (CommandLine::get_instance()->dl_uninstalled_deps_post.specified()) + options.uninstalled_deps_post = enum_arg_to_dep_list_deps_option( + CommandLine::get_instance()->dl_uninstalled_deps_post); + + if ((CommandLine::get_instance()->a_show_install_reasons.argument() == "summary") || + (CommandLine::get_instance()->a_show_install_reasons.argument() == "full")) + options.dependency_tags = true; + + OurInstallTask task(options); + task.set_no_config_protect(CommandLine::get_instance()->a_no_config_protection.specified()); + task.set_fetch_only(CommandLine::get_instance()->a_fetch.specified()); + task.set_pretend(CommandLine::get_instance()->a_pretend.specified()); + task.set_preserve_world(CommandLine::get_instance()->a_preserve_world.specified()); + + InstallKilledCatcher install_killed_catcher(task); + + try + { + for (CommandLine::ParametersIterator q(CommandLine::get_instance()->begin_parameters()), + q_end(CommandLine::get_instance()->end_parameters()) ; q != q_end ; ++q) + task.add_target(*q); + + 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; + show_resume_command(task); + 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; + show_resume_command(task); + 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; + } + catch (const HadBothPackageAndSetTargets &) + { + cout << endl; + cerr << "Error: both package sets and packages were specified." << endl; + cerr << endl; + cerr << "Package sets (like 'system' and 'world') cannot be installed at the same time" << endl; + cerr << "as ordinary packages." << endl; + + return_code |= 1; + } + catch (const MultipleSetTargetsSpecified &) + { + cout << endl; + cerr << "Error: multiple package sets were specified." << endl; + cerr << endl; + cerr << "Package sets (like 'system' and 'world') must be installed individually," << endl; + cerr << "without any other sets or packages." << endl; + + return_code |= 1; + } + + return return_code; +} + diff --git a/0.8.0/src/paludis/install.hh b/0.8.0/src/paludis/install.hh new file mode 100644 index 000000000..693931bb1 --- /dev/null +++ b/0.8.0/src/paludis/install.hh @@ -0,0 +1,32 @@ +/* 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_SRC_DEPGRAPH_HH +#define PALUDIS_GUARD_SRC_DEPGRAPH_HH 1 + +#include "command_line.hh" + +/** \file + * Declaration for the do_install function. + */ + +/// Handle --install. +int do_install(); + +#endif diff --git a/0.8.0/src/paludis/install_TEST b/0.8.0/src/paludis/install_TEST new file mode 100755 index 000000000..eab20a9d0 --- /dev/null +++ b/0.8.0/src/paludis/install_TEST @@ -0,0 +1,5 @@ +#!/bin/bash + +PALUDIS_HOME=./install_TEST_dir/config/ ./paludis --config-suffix install-test --install target || exit 1 +./install_TEST_dir/root/usr/bin/testbin | grep success >/dev/null + diff --git a/0.8.0/src/paludis/install_TEST_cleanup.sh b/0.8.0/src/paludis/install_TEST_cleanup.sh new file mode 100755 index 000000000..92bb92a5a --- /dev/null +++ b/0.8.0/src/paludis/install_TEST_cleanup.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# vim: set ft=sh sw=4 sts=4 et : + +if [ -d install_TEST_dir ] ; then + rm -fr install_TEST_dir +else + true +fi + + + diff --git a/0.8.0/src/paludis/install_TEST_setup.sh b/0.8.0/src/paludis/install_TEST_setup.sh new file mode 100755 index 000000000..b511e8ea9 --- /dev/null +++ b/0.8.0/src/paludis/install_TEST_setup.sh @@ -0,0 +1,121 @@ +#!/bin/bash +# vim: set ft=sh sw=4 sts=4 et : + +mkdir install_TEST_dir || exit 1 +cd install_TEST_dir || exit 1 + +mkdir -p config/.paludis-install-test +cat <<END > config/.paludis-install-test/specpath +root = `pwd`/root +config-suffix = +END + +mkdir -p root/${SYSCONFDIR}/paludis/repositories +cat <<END > root/${SYSCONFDIR}/paludis/use.conf +* foo +END + +cat <<END > root/${SYSCONFDIR}/paludis/licenses.conf +* * +END + +cat <<END > root/${SYSCONFDIR}/paludis/keywords.conf +* test +END + +cat <<END > root/${SYSCONFDIR}/paludis/bashrc +export CHOST="my-chost" +export USER_BASHRC_WAS_USED=yes +END + +cat <<END > root/${SYSCONFDIR}/paludis/repositories/repo1.conf +location = `pwd`/repo1 +cache = /var/empty +format = portage +profiles = \${location}/profiles/testprofile \${location}/profiles/anothertestprofile +buildroot = `pwd`/build +END + +mkdir -p root/tmp +touch root/${SYSCONFDIR}/ld.so.conf + +mkdir -p repo1/{eclass,distfiles,profiles/{testprofile,anothertestprofile},test-category/target/files} || exit 1 + +mkdir -p src/target-2 +cat <<"END" > src/target-2/testbin +#!/bin/bash +echo "Test was a success" +END +chmod +x src/target-2/testbin +cd src +tar zcf target-2.tar.gz target-2/ +mv target-2.tar.gz ../repo1/distfiles/ +cd .. +rm -fr src + +cd repo1 || exit 1 +echo "test-repo-1" > profiles/repo_name || exit 1 +cat <<END > profiles/categories || exit 1 +test-category +END +cat <<END > profiles/testprofile/make.defaults +ARCH=test +USERLAND=test +KERNEL=test +TESTPROFILE_WAS_SOURCED=yes +PROFILE_ORDERING=1 +END +cat <<END > profiles/anothertestprofile/make.defaults +ARCH=test +USERLAND=test +KERNEL=test +ANOTHERTESTPROFILE_WAS_SOURCED=yes +PROFILE_ORDERING=2 +END + +cat <<"END" > eclass/foo.eclass +inherit_was_ok() { + true +} +END + +cat <<"END" > test-category/target/target-2.ebuild || exit 1 +inherit foo + +DESCRIPTION="Test target" +HOMEPAGE="http://paludis.berlios.de/" +SRC_URI="http://invalid.domain/${P}.tar.gz oink? ( http://example.com/foo.tar.gz )" +SLOT="0" +IUSE="oink" +LICENSE="GPL-2" +KEYWORDS="test" + +pkg_setup() { + [[ -z "${USER_BASHRC_WAS_USED}" ]] && die "bad env" + [[ -z "${TESTPROFILE_WAS_SOURCED}" ]] && die "testprofile not sourced" + [[ -z "${ANOTHERTESTPROFILE_WAS_SOURCED}" ]] && die "anothertestprofile not sourced" + [[ ${PROFILE_ORDERING:-0} != 2 ]] && die "bad profile source ordering" +} + +src_unpack() { + hasq "${P}.tar.gz" ${A} || die + hasq "${P}.tar.gz" ${AA} || die + hasq "foo.tar.gz" ${A} && die + hasq "foo.tar.gz" ${AA} || die + unpack ${A} +} + +src_compile() { + inherit_was_ok || die "inherit didn't work" +} + +src_test() { + ./testbin | grep success || die "failure" +} + +src_install() { + dobin testbin +} +END +cd .. + diff --git a/0.8.0/src/paludis/licence.cc b/0.8.0/src/paludis/licence.cc new file mode 100644 index 000000000..a460a97cb --- /dev/null +++ b/0.8.0/src/paludis/licence.cc @@ -0,0 +1,66 @@ +/* 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 "licence.hh" +#include "colour.hh" +#include <ostream> + +void +LicenceDisplayer::visit(const paludis::AllDepAtom * atom) +{ + stream << "( "; + std::for_each(atom->begin(), atom->end(), paludis::accept_visitor(this)); + stream << ") "; +} + +void +LicenceDisplayer::visit(const paludis::AnyDepAtom * atom) +{ + stream << "|| ( "; + std::for_each(atom->begin(), atom->end(), paludis::accept_visitor(this)); + stream << ") "; +} + +void +LicenceDisplayer::visit(const paludis::UseDepAtom * atom) +{ + stream << atom->flag() << "? ( "; + std::for_each(atom->begin(), atom->end(), paludis::accept_visitor(this)); + stream << ") "; +} + +void +LicenceDisplayer::visit(const paludis::PlainTextDepAtom * atom) +{ + if (env->accept_license(atom->text(), db_entry)) + stream << colour(cl_not_masked, atom->text()); + else + stream << colour(cl_masked, "(" + atom->text() + ")!"); + stream << " "; +} + +LicenceDisplayer::LicenceDisplayer( + std::ostream & s, + const paludis::Environment * const e, + const paludis::PackageDatabaseEntry * const d) : + stream(s), + env(e), + db_entry(d) +{ +} diff --git a/0.8.0/src/paludis/licence.hh b/0.8.0/src/paludis/licence.hh new file mode 100644 index 000000000..38d902ea4 --- /dev/null +++ b/0.8.0/src/paludis/licence.hh @@ -0,0 +1,67 @@ +/* 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_SRC_LICENCE_HH +#define PALUDIS_GUARD_SRC_LICENCE_HH 1 + +#include <paludis/paludis.hh> +#include <iosfwd> + +/** + * Display licences. + */ +struct LicenceDisplayer : + paludis::DepAtomVisitorTypes::ConstVisitor +{ + /// Our stream. + std::ostream & stream; + + /// Our environment. + const paludis::Environment * const env; + + /// Our db entry. + const paludis::PackageDatabaseEntry * const db_entry; + + /// Constructor. + LicenceDisplayer( + std::ostream & stream, + const paludis::Environment * const e, + const paludis::PackageDatabaseEntry * const d); + + ///\name Visit methods + ///{ + void visit(const paludis::AllDepAtom * atom); + + void visit(const paludis::AnyDepAtom * atom); + + void visit(const paludis::UseDepAtom * atom); + + void visit(const paludis::PlainTextDepAtom * atom); + + void visit(const paludis::PackageDepAtom *) + { + } + + void visit(const paludis::BlockDepAtom *) + { + } + ///} +}; + +#endif diff --git a/0.8.0/src/paludis/list.cc b/0.8.0/src/paludis/list.cc new file mode 100644 index 000000000..5b93fc1d0 --- /dev/null +++ b/0.8.0/src/paludis/list.cc @@ -0,0 +1,338 @@ +/* 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 "colour.hh" +#include "command_line.hh" +#include "list.hh" +#include <iomanip> +#include <iostream> +#include <list> +#include <map> +#include <paludis/paludis.hh> +#include <paludis/environment/default/default_environment.hh> +#include <paludis/util/log.hh> +#include <paludis/util/visitor.hh> + +namespace p = paludis; + +int +do_list_repositories() +{ + int ret_code(1); + + p::Context context("When performing list-repositories action from command line:"); + p::Environment * const env(p::DefaultEnvironment::get_instance()); + + for (p::IndirectIterator<p::PackageDatabase::RepositoryIterator, const p::Repository> + r(env->package_database()->begin_repositories()), r_end(env->package_database()->end_repositories()) ; + r != r_end ; ++r) + { + if (CommandLine::get_instance()->a_repository.specified()) + if (CommandLine::get_instance()->a_repository.args_end() == std::find( + CommandLine::get_instance()->a_repository.args_begin(), + CommandLine::get_instance()->a_repository.args_end(), + stringify(r->name()))) + continue; + + ret_code = 0; + + std::cout << "* " << colour(cl_repository_name, r->name()) << std::endl; + + p::RepositoryInfo::ConstPointer ii(r->info(false)); + for (p::RepositoryInfo::SectionIterator i(ii->begin_sections()), + i_end(ii->end_sections()) ; i != i_end ; ++i) + { + std::cout << " " << colour(cl_heading, (*i)->heading() + ":") << std::endl; + for (p::RepositoryInfoSection::KeyValueIterator k((*i)->begin_kvs()), + k_end((*i)->end_kvs()) ; k != k_end ; ++k) + std::cout << " " << std::setw(22) << std::left << (p::stringify(k->first) + ":") + << std::setw(0) << " " << k->second << std::endl; + std::cout << std::endl; + } + } + + return ret_code; +} + +int +do_list_categories() +{ + int ret_code(1); + + p::Context context("When performing list-categories action from command line:"); + p::Environment * const env(p::DefaultEnvironment::get_instance()); + + std::map<p::CategoryNamePart, std::list<p::RepositoryName> > cats; + + for (p::IndirectIterator<p::PackageDatabase::RepositoryIterator, const p::Repository> + r(env->package_database()->begin_repositories()), r_end(env->package_database()->end_repositories()) ; + r != r_end ; ++r) + { + if (CommandLine::get_instance()->a_repository.specified()) + if (CommandLine::get_instance()->a_repository.args_end() == std::find( + CommandLine::get_instance()->a_repository.args_begin(), + CommandLine::get_instance()->a_repository.args_end(), + stringify(r->name()))) + continue; + + p::CategoryNamePartCollection::ConstPointer cat_names(r->category_names()); + for (p::CategoryNamePartCollection::Iterator c(cat_names->begin()), c_end(cat_names->end()) ; + c != c_end ; ++c) + cats[*c].push_back(r->name()); + } + + for (std::map<p::CategoryNamePart, std::list<p::RepositoryName > >::const_iterator + c(cats.begin()), c_end(cats.end()) ; c != c_end ; ++c) + { + if (CommandLine::get_instance()->a_category.specified()) + if (CommandLine::get_instance()->a_category.args_end() == std::find( + CommandLine::get_instance()->a_category.args_begin(), + CommandLine::get_instance()->a_category.args_end(), + stringify(c->first))) + continue; + + ret_code = 0; + + std::cout << "* " << colour(cl_package_name, c->first) << std::endl; + std::cout << " " << std::setw(22) << std::left << "found in:" << + std::setw(0) << " " << p::join(c->second.begin(), c->second.end(), ", ") << std::endl; + std::cout << std::endl; + } + + return ret_code; +} + +int +do_list_packages() +{ + int ret_code(1); + + p::Context context("When performing list-packages action from command line:"); + p::Environment * const env(p::DefaultEnvironment::get_instance()); + + std::map<p::QualifiedPackageName, std::list<p::RepositoryName> > pkgs; + + for (p::IndirectIterator<p::PackageDatabase::RepositoryIterator, const p::Repository> + r(env->package_database()->begin_repositories()), r_end(env->package_database()->end_repositories()) ; + r != r_end ; ++r) + { + if (CommandLine::get_instance()->a_repository.specified()) + if (CommandLine::get_instance()->a_repository.args_end() == std::find( + CommandLine::get_instance()->a_repository.args_begin(), + CommandLine::get_instance()->a_repository.args_end(), + stringify(r->name()))) + continue; + + p::CategoryNamePartCollection::ConstPointer cat_names(r->category_names()); + for (p::CategoryNamePartCollection::Iterator c(cat_names->begin()), c_end(cat_names->end()) ; + c != c_end ; ++c) + { + if (CommandLine::get_instance()->a_category.specified()) + if (CommandLine::get_instance()->a_category.args_end() == std::find( + CommandLine::get_instance()->a_category.args_begin(), + CommandLine::get_instance()->a_category.args_end(), + stringify(*c))) + continue; + + p::QualifiedPackageNameCollection::ConstPointer pkg_names(r->package_names(*c)); + for (p::QualifiedPackageNameCollection::Iterator p(pkg_names->begin()), p_end(pkg_names->end()) ; + p != p_end ; ++p) + pkgs[*p].push_back(r->name()); + } + } + + for (std::map<p::QualifiedPackageName, std::list<p::RepositoryName > >::const_iterator + p(pkgs.begin()), p_end(pkgs.end()) ; p != p_end ; ++p) + { + if (CommandLine::get_instance()->a_package.specified()) + if (CommandLine::get_instance()->a_package.args_end() == std::find( + CommandLine::get_instance()->a_package.args_begin(), + CommandLine::get_instance()->a_package.args_end(), + stringify(p->first.package))) + continue; + + ret_code = 0; + + std::cout << "* " << colour(cl_package_name, p->first) << std::endl; + std::cout << " " << std::setw(22) << std::left << "found in:" << + std::setw(0) << " " << p::join(p->second.begin(), p->second.end(), ", ") << std::endl; + std::cout << std::endl; + } + + return ret_code; +} + +int +do_list_sets() +{ + int ret_code(1); + + p::Context context("While performing list-sets action from command line:"); + p::Environment * const env(p::DefaultEnvironment::get_instance()); + + std::map<std::string, std::list<p::RepositoryName> > sets; + + for (p::IndirectIterator<p::PackageDatabase::RepositoryIterator, const p::Repository> + r(env->package_database()->begin_repositories()), r_end(env->package_database()->end_repositories()) ; + r != r_end ; ++r) + { + if (r->sets_interface == 0) + continue; + + if (CommandLine::get_instance()->a_repository.specified()) + if (CommandLine::get_instance()->a_repository.args_end() == std::find( + CommandLine::get_instance()->a_repository.args_begin(), + CommandLine::get_instance()->a_repository.args_end(), + stringify(r->name()))) + continue; + + p::SetsCollection::ConstPointer set_names(r->sets_interface->sets_list()); + for (p::SetsCollection::Iterator s(set_names->begin()), s_end(set_names->end()) ; + s != s_end ; ++s) + sets[*s].push_back(r->name()); + } + + for (std::map<std::string, std::list<p::RepositoryName > >::const_iterator + s(sets.begin()), s_end(sets.end()) ; s != s_end ; ++s) + { + if (CommandLine::get_instance()->a_set.specified()) + if (CommandLine::get_instance()->a_set.args_end() == std::find( + CommandLine::get_instance()->a_set.args_begin(), + CommandLine::get_instance()->a_set.args_end(), + s->first)) + continue; + + ret_code = 0; + + std::cout << "* " << colour(cl_package_name, s->first) << std::endl; + std::cout << " " << std::setw(22) << std::left << "found in:" << + std::setw(0) << " " << p::join(s->second.begin(), s->second.end(), ", ") << std::endl; + std::cout << std::endl; + } + + return ret_code; +} + +namespace +{ + /** + * Print dependency atoms as returned by do_package_set("security"). + * + * \ingroup grpvulnerabilitiesprinter + */ + class VulnerabilitiesPrinter : + public p::DepAtomVisitorTypes::ConstVisitor + { + private: + unsigned _size; + + public: + /** + * Constructor. + */ + VulnerabilitiesPrinter() : + _size(0) + { + } + + /// \name Visit functions + ///{ + void visit(const p::AllDepAtom * const); + + void visit(const p::AnyDepAtom * const); + + void visit(const p::UseDepAtom * const); + + void visit(const p::PackageDepAtom * const); + + void visit(const p::PlainTextDepAtom * const); + + void visit(const p::BlockDepAtom * const); + ///} + + /** + * Return number of visited atoms. + */ + unsigned size() const + { + return _size; + } + }; + + void + VulnerabilitiesPrinter::visit(const p::AllDepAtom * const a) + { + std::for_each(a->begin(), a->end(), p::accept_visitor(this)); + } + + void + VulnerabilitiesPrinter::visit(const p::AnyDepAtom * const a) + { + std::for_each(a->begin(), a->end(), p::accept_visitor(this)); + } + + void + VulnerabilitiesPrinter::visit(const p::UseDepAtom * const a) + { + p::Log::get_instance()->message(p::ll_warning, p::lc_no_context, + "UseDepAtom encounter in do_package_set(\"security\")."); + std::for_each(a->begin(), a->end(), p::accept_visitor(this)); + } + + void + VulnerabilitiesPrinter::visit(const p::PackageDepAtom * const a) + { + p::QualifiedPackageName q(a->package()); + + std::string c(p::stringify(q.category)); + if (CommandLine::get_instance()->a_category.specified()) + if (CommandLine::get_instance()->a_category.args_end() == std::find( + CommandLine::get_instance()->a_category.args_begin(), + CommandLine::get_instance()->a_category.args_end(), + c)) + return; + + std::string p(p::stringify(q.package)); + if (CommandLine::get_instance()->a_package.specified()) + if (CommandLine::get_instance()->a_package.args_end() == std::find( + CommandLine::get_instance()->a_package.args_begin(), + CommandLine::get_instance()->a_package.args_end(), + p)) + return; + + std::cout << "* " << colour(cl_package_name, p::stringify(q)); + if (0 != a->tag()) + std::cout << "-" << p::stringify(*a->version_spec_ptr()); + if (0 != a->tag()) + std::cout << " " << colour(cl_tag, "<" + a->tag()->short_text() + ">"); + std::cout << std::endl; + ++_size; + } + + void + VulnerabilitiesPrinter::visit(const p::PlainTextDepAtom * const) + { + } + + void + VulnerabilitiesPrinter::visit(const p::BlockDepAtom * const) + { + } +} + diff --git a/0.8.0/src/paludis/list.hh b/0.8.0/src/paludis/list.hh new file mode 100644 index 000000000..204af50f3 --- /dev/null +++ b/0.8.0/src/paludis/list.hh @@ -0,0 +1,39 @@ +/* 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_SRC_LIST_REPOSITORIES_HH +#define PALUDIS_GUARD_SRC_LIST_REPOSITORIES_HH 1 + +/** \file + * Declaration for the do_list_repositories and do_list_categories functions. + */ + +/// Handle --list-repositories. +int do_list_repositories(); + +/// Handle --list-categories. +int do_list_categories(); + +/// Handle --list-packages. +int do_list_packages(); + +/// Handle --list-sets. +int do_list_sets(); + +#endif diff --git a/0.8.0/src/paludis/list_dep_tag_categories_TEST b/0.8.0/src/paludis/list_dep_tag_categories_TEST new file mode 100755 index 000000000..40fa15c1a --- /dev/null +++ b/0.8.0/src/paludis/list_dep_tag_categories_TEST @@ -0,0 +1,3 @@ +#!/bin/bash + +PALUDIS_SKIP_CONFIG=yes ./paludis --list-dep-tag-categories diff --git a/0.8.0/src/paludis/list_repository_formats_TEST b/0.8.0/src/paludis/list_repository_formats_TEST new file mode 100755 index 000000000..487513c46 --- /dev/null +++ b/0.8.0/src/paludis/list_repository_formats_TEST @@ -0,0 +1,3 @@ +#!/bin/bash + +PALUDIS_SKIP_CONFIG=yes ./paludis --list-repository-formats diff --git a/0.8.0/src/paludis/list_sync_formats_TEST b/0.8.0/src/paludis/list_sync_formats_TEST new file mode 100755 index 000000000..f638b2263 --- /dev/null +++ b/0.8.0/src/paludis/list_sync_formats_TEST @@ -0,0 +1,3 @@ +#!/bin/bash + +PALUDIS_SKIP_CONFIG=yes ./paludis --list-sync-protocols diff --git a/0.8.0/src/paludis/man_paludis.cc b/0.8.0/src/paludis/man_paludis.cc new file mode 100644 index 000000000..9cab7e5d5 --- /dev/null +++ b/0.8.0/src/paludis/man_paludis.cc @@ -0,0 +1,35 @@ +/* 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 "command_line.hh" +#include <paludis/args/man.hh> + +#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/0.8.0/src/paludis/news.cc b/0.8.0/src/paludis/news.cc new file mode 100644 index 000000000..17df87a45 --- /dev/null +++ b/0.8.0/src/paludis/news.cc @@ -0,0 +1,52 @@ +/* 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 "colour.hh" +#include "news.hh" +#include <functional> +#include <iomanip> +#include <iostream> +#include <paludis/paludis.hh> +#include <paludis/environment/default/default_environment.hh> +#include <string> + +/** \file + * Handle the --update-news action for the main paludis program. + */ + +namespace p = paludis; + +int +do_update_news() +{ + int return_code(0); + + p::Context context("When performing update-news action from command line:"); + p::Environment * const env(p::DefaultEnvironment::get_instance()); + + for (p::PackageDatabase::RepositoryIterator r(env->package_database()->begin_repositories()), + r_end(env->package_database()->end_repositories()) ; r != r_end ; ++r) + if ((*r)->news_interface) + (*r)->news_interface->update_news(); + + return return_code; +} + + + diff --git a/0.8.0/src/paludis/news.hh b/0.8.0/src/paludis/news.hh new file mode 100644 index 000000000..1e3e06d11 --- /dev/null +++ b/0.8.0/src/paludis/news.hh @@ -0,0 +1,34 @@ +/* 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_SRC_NEWS_HH +#define PALUDIS_GUARD_SRC_NEWS_HH 1 + +#include "command_line.hh" + +/** \file + * Declaration for the do_update_news function. + */ + +/// Handle --update-news. +int do_update_news(); + +#endif + + diff --git a/0.8.0/src/paludis/owner.cc b/0.8.0/src/paludis/owner.cc new file mode 100644 index 000000000..4d63bf129 --- /dev/null +++ b/0.8.0/src/paludis/owner.cc @@ -0,0 +1,133 @@ +/* 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 "owner.hh" +#include "colour.hh" +#include "command_line.hh" +#include <paludis/paludis.hh> +#include <paludis/environment/default/default_environment.hh> +#include <iostream> + +namespace p = paludis; +using std::cout; +using std::cerr; +using std::endl; + +namespace +{ + struct ContentsFinder : + p::ContentsVisitorTypes::ConstVisitor + { + bool found; + const std::string query; + const bool full; + + ContentsFinder(const std::string & q, bool f) : + found(false), + query(q), + full(f) + { + } + + void handle(const std::string & e) + { + if (full) + found |= (e == query); + else + found |= (std::string::npos != e.find(query)); + } + + void visit(const p::ContentsFileEntry * const e) + { + handle(e->name()); + } + + void visit(const p::ContentsDirEntry * const e) + { + handle(e->name()); + } + + void visit(const p::ContentsSymEntry * const e) + { + handle(e->name()); + } + + void visit(const p::ContentsMiscEntry * const e) + { + handle(e->name()); + } + }; +} + +void +do_one_owner( + const p::Environment * const env, + const std::string & query) +{ + cout << "* " << colour(cl_package_name, query) << endl; + + for (p::PackageDatabase::RepositoryIterator r(env->package_database()->begin_repositories()), + r_end(env->package_database()->end_repositories()) ; r != r_end ; ++r) + { + if (! (*r)->installed_interface) + continue; + + p::CategoryNamePartCollection::ConstPointer cats((*r)->category_names()); + for (p::CategoryNamePartCollection::Iterator c(cats->begin()), + c_end(cats->end()) ; c != c_end ; ++c) + { + p::QualifiedPackageNameCollection::ConstPointer pkgs((*r)->package_names(*c)); + for (p::QualifiedPackageNameCollection::Iterator p(pkgs->begin()), + p_end(pkgs->end()) ; p != p_end ; ++p) + { + p::VersionSpecCollection::ConstPointer vers((*r)->version_specs(*p)); + for (p::VersionSpecCollection::Iterator v(vers->begin()), + v_end(vers->end()) ; v != v_end ; ++v) + { + p::PackageDatabaseEntry e(*p, *v, (*r)->name()); + p::Contents::ConstPointer contents((*r)->installed_interface-> + contents(*p, *v)); + ContentsFinder d(query, CommandLine::get_instance()->a_full_match.specified()); + std::for_each(contents->begin(), contents->end(), accept_visitor(&d)); + if (d.found) + cout << " " << e << endl; + } + } + } + } + + cout << endl; +} + + +int +do_owner() +{ + int return_code(0); + p::Context context("When performing owner action from command line:"); + p::Environment * const env(p::DefaultEnvironment::get_instance()); + + CommandLine::ParametersIterator q(CommandLine::get_instance()->begin_parameters()), + q_end(CommandLine::get_instance()->end_parameters()); + for ( ; q != q_end ; ++q) + do_one_owner(env, *q); + + return return_code; +} + diff --git a/0.8.0/src/paludis/owner.hh b/0.8.0/src/paludis/owner.hh new file mode 100644 index 000000000..ce9efba9a --- /dev/null +++ b/0.8.0/src/paludis/owner.hh @@ -0,0 +1,30 @@ +/* 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_SRC_OWNER_HH +#define PALUDIS_GUARD_SRC_OWNER_HH 1 + +/** \file + * Declaration for the do_owner function. + */ + +/// Handle --owner. +int do_owner(); + +#endif diff --git a/0.8.0/src/paludis/paludis.cc b/0.8.0/src/paludis/paludis.cc new file mode 100644 index 000000000..e44e79111 --- /dev/null +++ b/0.8.0/src/paludis/paludis.cc @@ -0,0 +1,443 @@ +/* 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 "applets.hh" +#include "colour.hh" +#include "command_line.hh" +#include "contents.hh" +#include "install.hh" +#include "list.hh" +#include "news.hh" +#include "owner.hh" +#include "query.hh" +#include "sync.hh" +#include "uninstall.hh" +#include "config.h" + +#include <paludis/paludis.hh> +#include <paludis/util/util.hh> +#include <paludis/environment/default/default_environment.hh> +#include <paludis/environment/default/default_config.hh> + +#include <libebt/libebt.hh> +#include <libwrapiter/libwrapiter.hh> + +#include <iostream> +#include <iomanip> +#include <string> +#include <cstdlib> + +/** \file + * Main paludis program. + */ + +namespace p = paludis; + +using std::cout; +using std::cerr; +using std::endl; + +#ifndef DOXYGEN +struct DoVersion +{ +}; +#endif + +namespace +{ + void display_version() + { + cout << 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 << "DATADIR: " << DATADIR << endl; + cout << "LIBDIR: " << LIBDIR << endl; + cout << "LIBEXECDIR: " << LIBEXECDIR << endl; + cout << "SYSCONFDIR: " << SYSCONFDIR << 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; +#if HAVE_SANDBOX + cout << "sandbox: enabled" << endl; +#else + cout << "sandbox: disabled" << endl; +#endif + } + + void display_info() + { + p::Environment * const env(p::DefaultEnvironment::get_instance()); + + for (p::IndirectIterator<p::PackageDatabase::RepositoryIterator, const p::Repository> + r(env->package_database()->begin_repositories()), r_end(env->package_database()->end_repositories()) ; + r != r_end ; ++r) + { + cout << "Repository " << colour(cl_repository_name, r->name()) << ":" << endl; + + p::RepositoryInfo::ConstPointer ii(r->info(true)); + for (p::RepositoryInfo::SectionIterator i(ii->begin_sections()), + i_end(ii->end_sections()) ; i != i_end ; ++i) + { + cout << " " << colour(cl_heading, (*i)->heading() + ":") << endl; + for (p::RepositoryInfoSection::KeyValueIterator k((*i)->begin_kvs()), + k_end((*i)->end_kvs()) ; k != k_end ; ++k) + cout << " " << std::setw(22) << std::left << (p::stringify(k->first) + ":") + << std::setw(0) << " " << k->second << endl; + cout << endl; + } + } + + } +} + +int +main(int argc, char *argv[]) +{ + p::Context context("In program " + p::join(argv, argv + argc, " ") + ":"); + + try + { + CommandLine::get_instance()->run(argc, argv); + set_use_colour(! CommandLine::get_instance()->a_no_color.specified()); + + if (CommandLine::get_instance()->a_help.specified()) + throw DoHelp(); + + if (CommandLine::get_instance()->a_version.specified()) + throw DoVersion(); + + if (! CommandLine::get_instance()->a_log_level.specified()) + p::Log::get_instance()->set_log_level(p::ll_qa); + else if (CommandLine::get_instance()->a_log_level.argument() == "debug") + p::Log::get_instance()->set_log_level(p::ll_debug); + else if (CommandLine::get_instance()->a_log_level.argument() == "qa") + p::Log::get_instance()->set_log_level(p::ll_qa); + else if (CommandLine::get_instance()->a_log_level.argument() == "warning") + p::Log::get_instance()->set_log_level(p::ll_warning); + else if (CommandLine::get_instance()->a_log_level.argument() == "silent") + p::Log::get_instance()->set_log_level(p::ll_silent); + else + throw DoHelp("bad value for --log-level"); + + p::Log::get_instance()->set_program_name(argv[0]); + + if (1 != (CommandLine::get_instance()->a_query.specified() + + CommandLine::get_instance()->a_version.specified() + + CommandLine::get_instance()->a_install.specified() + + CommandLine::get_instance()->a_uninstall.specified() + + CommandLine::get_instance()->a_sync.specified() + + CommandLine::get_instance()->a_list_repositories.specified() + + CommandLine::get_instance()->a_list_categories.specified() + + CommandLine::get_instance()->a_list_packages.specified() + + CommandLine::get_instance()->a_list_sets.specified() + + CommandLine::get_instance()->a_list_sync_protocols.specified() + + CommandLine::get_instance()->a_list_repository_formats.specified() + + CommandLine::get_instance()->a_list_dep_tag_categories.specified() + + CommandLine::get_instance()->a_contents.specified() + + CommandLine::get_instance()->a_owner.specified() + + CommandLine::get_instance()->a_has_version.specified() + + CommandLine::get_instance()->a_update_news.specified() + + CommandLine::get_instance()->a_environment_variable.specified() + + CommandLine::get_instance()->a_configuration_variable.specified() + + CommandLine::get_instance()->a_info.specified() + + CommandLine::get_instance()->a_best_version.specified())) + { + if ((1 == std::distance(CommandLine::get_instance()->begin_parameters(), + CommandLine::get_instance()->end_parameters())) && + ("moo" == *CommandLine::get_instance()->begin_parameters())) + { + cout << endl; + cout << " ______________________________" << endl; + cout << "( Ugh. Another Portage user... )" << endl; + cout << " ------------------------------ " << endl; + cout << " o" << endl; + cout << " o" << endl; + cout << " ^__^ /" << endl; + cout << " (" << colour(cl_bold_pink, "oo") << ")\\_______/ _________" << endl; + cout << " (__)\\ )=( ____|_ \\_____" << endl; + cout << " ||----w | \\ \\ \\_____ |" << endl; + cout << " || || || ||" << endl; + cout << endl; + return EXIT_SUCCESS; + } + else + throw DoHelp("you should specify exactly one action"); + } + + /* these actions don't need DefaultConfig */ + + if (CommandLine::get_instance()->a_list_sync_protocols.specified()) + { + if (! CommandLine::get_instance()->empty()) + throw DoHelp("list-sync-protocols action takes no parameters"); + + return do_list_sync_protocols(); + } + + if (CommandLine::get_instance()->a_list_repository_formats.specified()) + { + if (! CommandLine::get_instance()->empty()) + throw DoHelp("list-repository-formats action takes no parameters"); + + return do_list_repository_formats(); + } + + if (CommandLine::get_instance()->a_list_dep_tag_categories.specified()) + { + if (! CommandLine::get_instance()->empty()) + throw DoHelp("list-dep-tag-categories action takes no parameters"); + + return do_list_dep_tag_categories(); + } + + /* these actions do need DefaultConfig */ + + try + { + std::string paludis_command(argv[0]); + if (CommandLine::get_instance()->a_config_suffix.specified()) + { + p::DefaultConfig::set_config_suffix(CommandLine::get_instance()->a_config_suffix.argument()); + paludis_command.append(" --config-suffix " + + CommandLine::get_instance()->a_config_suffix.argument()); + } + paludis_command.append(" --log-level " + CommandLine::get_instance()->a_log_level.argument()); + p::DefaultConfig::get_instance()->set_paludis_command(paludis_command); + } + catch (const p::DefaultConfigError & e) + { + if (CommandLine::get_instance()->a_info.specified()) + { + display_version(); + cout << endl; + cout << "Cannot complete --info output due to configuration exception" << endl; + } + throw; + } + + if (CommandLine::get_instance()->a_info.specified()) + { + display_version(); + cout << endl; + display_info(); + cout << endl; + return EXIT_SUCCESS; + } + + if (CommandLine::get_instance()->a_query.specified()) + { + if (CommandLine::get_instance()->empty()) + throw DoHelp("query action requires at least one parameter"); + + return do_query(); + } + + if (CommandLine::get_instance()->a_install.specified()) + { + if (CommandLine::get_instance()->empty()) + throw DoHelp("install action requires at least one parameter"); + + return do_install(); + } + + if (CommandLine::get_instance()->a_uninstall.specified()) + { + if (CommandLine::get_instance()->empty()) + throw DoHelp("uninstall action requires at least one parameter"); + + return do_uninstall(); + } + + if (CommandLine::get_instance()->a_sync.specified()) + { + return do_sync(); + } + + if (CommandLine::get_instance()->a_list_repositories.specified()) + { + if (! CommandLine::get_instance()->empty()) + throw DoHelp("list-repositories action takes no parameters"); + + return do_list_repositories(); + } + + if (CommandLine::get_instance()->a_list_categories.specified()) + { + if (! CommandLine::get_instance()->empty()) + throw DoHelp("list-categories action takes no parameters"); + + return do_list_categories(); + } + + if (CommandLine::get_instance()->a_list_packages.specified()) + { + if (! CommandLine::get_instance()->empty()) + throw DoHelp("list-packages action takes no parameters"); + + return do_list_packages(); + } + + if (CommandLine::get_instance()->a_list_sets.specified()) + { + if (! CommandLine::get_instance()->empty()) + throw DoHelp("list-sets action takes no parameters"); + + return do_list_sets(); + } + + if (CommandLine::get_instance()->a_contents.specified()) + { + if (CommandLine::get_instance()->empty()) + throw DoHelp("contents action requires at least one parameter"); + + return do_contents(); + } + + if (CommandLine::get_instance()->a_owner.specified()) + { + if (CommandLine::get_instance()->empty()) + throw DoHelp("owner action requires at least one parameter"); + + return do_owner(); + } + + if (CommandLine::get_instance()->a_has_version.specified()) + { + if (1 != std::distance(CommandLine::get_instance()->begin_parameters(), + CommandLine::get_instance()->end_parameters())) + throw DoHelp("has-version action takes exactly one parameter"); + + return do_has_version(); + } + + if (CommandLine::get_instance()->a_best_version.specified()) + { + if (1 != std::distance(CommandLine::get_instance()->begin_parameters(), + CommandLine::get_instance()->end_parameters())) + throw DoHelp("best-version action takes exactly one parameter"); + + return do_best_version(); + } + + if (CommandLine::get_instance()->a_environment_variable.specified()) + { + if (2 != std::distance(CommandLine::get_instance()->begin_parameters(), + CommandLine::get_instance()->end_parameters())) + throw DoHelp("environment-variable action takes exactly two parameters (depatom var)"); + + return do_environment_variable(); + } + + if (CommandLine::get_instance()->a_configuration_variable.specified()) + { + if (2 != std::distance(CommandLine::get_instance()->begin_parameters(), + CommandLine::get_instance()->end_parameters())) + throw DoHelp("configuration-variable action takes exactly two parameters (repository var)"); + + return do_configuration_variable(); + } + + if (CommandLine::get_instance()->a_update_news.specified()) + { + if (! CommandLine::get_instance()->empty()) + throw DoHelp("update-news action takes no parameters"); + + return do_update_news(); + } + + throw p::InternalError(__PRETTY_FUNCTION__, "no action?"); + } + catch (const DoVersion &) + { + display_version(); + 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 << 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 p::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/0.8.0/src/paludis/query.cc b/0.8.0/src/paludis/query.cc new file mode 100644 index 000000000..09b17259f --- /dev/null +++ b/0.8.0/src/paludis/query.cc @@ -0,0 +1,418 @@ +/* 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 "colour.hh" +#include "query.hh" +#include "licence.hh" +#include "use.hh" +#include <functional> +#include <iomanip> +#include <iostream> +#include <paludis/paludis.hh> +#include <paludis/util/collection_concrete.hh> +#include <paludis/environment/default/default_environment.hh> +#include <string> + +/** \file + * Handle the --query action for the main paludis program. + */ + +using namespace paludis; +using std::cout; +using std::cerr; +using std::endl; + +void do_one_package_query( + const Environment * const env, + const std::string & q, + MaskReasons & mask_reasons_to_explain, + PackageDepAtom::Pointer atom) +{ + /* prefer the best installed version, then the best visible version, then + * the best version */ + PackageDatabaseEntryCollection::ConstPointer + entries(env->package_database()->query(atom, is_either)), + preferred_entries(env->package_database()->query(atom, is_installed_only)); + if (entries->empty()) + throw NoSuchPackageError(q); + if (preferred_entries->empty()) + preferred_entries = entries; + + PackageDatabaseEntry display_entry(*preferred_entries->last()); + for (PackageDatabaseEntryCollection::Iterator i(preferred_entries->begin()), + i_end(preferred_entries->end()) ; i != i_end ; ++i) + if (! env->mask_reasons(*i).any()) + display_entry = *i; + + /* match! display it. */ + cout << "* " << colour(cl_package_name, entries->begin()->name); + if (atom->version_spec_ptr()) + cout << " (" << atom->version_operator() << *atom->version_spec_ptr() << ")"; + if (atom->slot_ptr()) + cout << " (:" << *atom->slot_ptr() << ")"; + if (atom->repository_ptr()) + cout << " (::" << *atom->repository_ptr() << ")"; + cout << endl; + + /* find all repository names. */ + RepositoryNameCollection::Concrete repo_names; + PackageDatabaseEntryCollection::Iterator e(entries->begin()), e_end(entries->end()); + for ( ; e != e_end ; ++e) + repo_names.append(e->repository); + + /* display versions, by repository. */ + RepositoryNameCollection::Iterator r(repo_names.begin()), r_end(repo_names.end()); + for ( ; r != r_end ; ++r) + { + cout << " " << std::setw(22) << std::left << + (stringify(*r) + ":") << std::setw(0) << " "; + + std::string old_slot; + for (e = entries->begin() ; e != e_end ; ++e) + { + Context context("When displaying entry '" + stringify(*e) + "':'"); + + if (e->repository == *r) + { + VersionMetadata::ConstPointer metadata(env->package_database()->fetch_repository( + e->repository)->version_metadata(e->name, + e->version)); + if (CommandLine::get_instance()->a_show_slot.specified()) + { + /* show the slot, if we're about to move onto a new slot */ + std::string slot_name(stringify(metadata->slot)); + if (old_slot.empty()) + old_slot = slot_name; + else if (old_slot != slot_name) + cout << colour(cl_slot, "{:" + old_slot + "} "); + old_slot = slot_name; + } + + const MaskReasons masks(env->mask_reasons(*e)); + + if (masks.none()) + cout << colour(cl_visible, e->version); + else + { + std::string reasons; + for (MaskReason m(MaskReason(0)) ; m < last_mr ; + m = MaskReason(static_cast<int>(m) + 1)) + { + if (! masks.test(m)) + continue; + + switch (m) + { + case mr_keyword: + reasons.append("K"); + break; + case mr_user_mask: + reasons.append("U"); + break; + case mr_profile_mask: + reasons.append("P"); + break; + case mr_repository_mask: + reasons.append("R"); + break; + case mr_eapi: + reasons.append("E"); + break; + case mr_license: + reasons.append("L"); + break; + case mr_by_association: + reasons.append("A"); + break; + case last_mr: + break; + } + } + mask_reasons_to_explain |= masks; + cout << colour(cl_masked, "(" + stringify(e->version) + ")" + reasons); + } + + if (*e == display_entry) + cout << "*"; + cout << " "; + } + } + + /* still need to show the slot for the last item */ + if (CommandLine::get_instance()->a_show_slot.specified()) + cout << colour(cl_slot, "{:" + old_slot + "} "); + + cout << endl; + } + + /* display metadata */ + VersionMetadata::ConstPointer metadata(env->package_database()->fetch_repository( + display_entry.repository)->version_metadata( + display_entry.name, display_entry.version)); + + if (CommandLine::get_instance()->a_show_metadata.specified()) + { + cout << " " << std::setw(22) << std::left << "DESCRIPTION:" << std::setw(0) << + " " << metadata->description << endl; + cout << " " << std::setw(22) << std::left << "HOMEPAGE:" << std::setw(0) << + " " << metadata->homepage << endl; + cout << " " << std::setw(22) << std::left << "LICENSE:" << std::setw(0) << + " " << metadata->license_string << endl; + + cout << " " << std::setw(22) << std::left << "DEPEND:" << std::setw(0) << + " " << metadata->deps.build_depend_string << endl; + cout << " " << std::setw(22) << std::left << "RDEPEND:" << std::setw(0) << + " " << metadata->deps.run_depend_string << endl; + cout << " " << std::setw(22) << std::left << "PDEPEND:" << std::setw(0) << + " " << metadata->deps.post_depend_string << endl; + + if (metadata->get_cran_interface()) + { + cout << " " << std::setw(22) << std::left << "KEYWORDS:" << std::setw(0) << + " " << metadata->get_cran_interface()->keywords << endl; + cout << " " << std::setw(22) << std::left << "PACKAGE:" << std::setw(0) << + " " << metadata->get_cran_interface()->package << endl; + cout << " " << std::setw(22) << std::left << "VERSION:" << std::setw(0) << + " " << metadata->get_cran_interface()->version << endl; + cout << " " << std::setw(22) << std::left << "IS_BUNDLE:" << std::setw(0) << + " " << std::boolalpha << metadata->get_cran_interface()->is_bundle << endl; + } + + if (metadata->get_ebuild_interface()) + { + cout << " " << std::setw(22) << std::left << "IUSE:" << std::setw(0) << + " " << metadata->get_ebuild_interface()->iuse << endl; + cout << " " << std::setw(22) << std::left << "KEYWORDS:" << std::setw(0) << + " " << metadata->get_ebuild_interface()->keywords << endl; + cout << " " << std::setw(22) << std::left << "PROVIDE:" << std::setw(0) << + " " << metadata->get_ebuild_interface()->provide_string << endl; + cout << " " << std::setw(22) << std::left << "RESTRICT:" << std::setw(0) << + " " << metadata->get_ebuild_interface()->restrict_string << endl; + cout << " " << std::setw(22) << std::left << "SRC_URI:" << std::setw(0) << + " " << metadata->get_ebuild_interface()->src_uri << endl; + } + + if (metadata->get_ebin_interface()) + { + cout << " " << std::setw(22) << std::left << "BIN_URI:" << std::setw(0) << + " " << metadata->get_ebin_interface()->bin_uri << endl; + cout << " " << std::setw(22) << std::left << "SRC_REPOSITORY:" << std::setw(0) << + " " << metadata->get_ebin_interface()->src_repository << endl; + } + } + else + { + if (! metadata->homepage.empty()) + cout << " " << std::setw(22) << std::left << "Homepage:" << std::setw(0) << + " " << metadata->homepage << endl; + + if (! metadata->description.empty()) + cout << " " << std::setw(22) << std::left << "Description:" << std::setw(0) << + " " << metadata->description << endl; + + if (! metadata->license_string.empty()) + { + cout << " " << std::setw(22) << std::left << "License:" << std::setw(0) << " "; + LicenceDisplayer d(cout, env, &display_entry); + metadata->license()->accept(&d); + cout << endl; + } + + if (CommandLine::get_instance()->a_show_deps.specified()) + { + if (! metadata->deps.build_depend_string.empty()) + { + DepAtomPrettyPrinter p_depend(12); + metadata->deps.build_depend()->accept(&p_depend); + cout << " " << std::setw(22) << std::left << "Build dependencies:" << std::setw(0) + << endl << p_depend; + } + + if (! metadata->deps.run_depend_string.empty()) + { + DepAtomPrettyPrinter p_depend(12); + metadata->deps.run_depend()->accept(&p_depend); + cout << " " << std::setw(22) << std::left << "Runtime dependencies:" << std::setw(0) + << endl << p_depend; + } + + if (! metadata->deps.post_depend_string.empty()) + { + DepAtomPrettyPrinter p_depend(12); + metadata->deps.post_depend()->accept(&p_depend); + cout << " " << std::setw(22) << std::left << "Post dependencies:" << std::setw(0) + << endl << p_depend; + } + } + + if (metadata->get_ebuild_interface()) + { + if (! metadata->get_ebuild_interface()->provide_string.empty()) + cout << " " << std::setw(22) << std::left << "Provides:" << std::setw(0) << + " " << metadata->get_ebuild_interface()->provide_string << endl; + + if (! metadata->get_ebuild_interface()->iuse.empty()) + cout << " " << std::setw(22) << std::left << "Use flags:" << std::setw(0) << + " " << make_pretty_use_flags_string(DefaultEnvironment::get_instance(), + display_entry, metadata) << endl; + } + + if (metadata->get_virtual_interface()) + cout << " " << std::setw(22) << std::left << "Virtual for:" << std::setw(0) << + " " << metadata->get_virtual_interface()->virtual_for << endl; + } + + + /* blank line */ + cout << endl; +} + +void do_one_set_query( + const Environment * const, + const std::string & q, + MaskReasons &, + DepAtom::Pointer set) +{ + cout << "* " << colour(cl_package_name, q) << endl; + DepAtomPrettyPrinter packages(12); + set->accept(&packages); + cout << " " << std::setw(22) << std::left << "Packages:" << std::setw(0) + << endl << packages << endl; +} + +void do_one_query( + const Environment * const env, + const std::string & q, + MaskReasons & mask_reasons_to_explain) +{ + Context local_context("When handling query '" + q + "':"); + + /* we might have a dep atom, but we might just have a simple package name + * without a category. or it might be a set... all should work. */ + PackageDepAtom::Pointer atom(0); + DepAtom::Pointer set(0); + if (std::string::npos == q.find('/')) + { + if (0 == ((set = env->package_set(q)))) + atom.assign(new PackageDepAtom(env->package_database()->fetch_unique_qualified_package_name( + PackageNamePart(q)))); + } + else + atom.assign(new PackageDepAtom(q)); + + if (atom) + do_one_package_query(env, q, mask_reasons_to_explain, atom); + else + do_one_set_query(env, q, mask_reasons_to_explain, set); +} + +int do_query() +{ + int return_code(0); + + Context context("When performing query action from command line:"); + Environment * const env(DefaultEnvironment::get_instance()); + + MaskReasons mask_reasons_to_explain; + + CommandLine::ParametersIterator q(CommandLine::get_instance()->begin_parameters()), + q_end(CommandLine::get_instance()->end_parameters()); + for ( ; q != q_end ; ++q) + { + try + { + do_one_query(env, *q, mask_reasons_to_explain); + } + 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; + } + catch (const NameError & e) + { + return_code |= 1; + cout << endl; + cerr << "Query error:" << endl; + cerr << " * " << e.backtrace("\n * ") << e.message() << endl; + cerr << endl; + } + catch (const PackageDatabaseLookupError & e) + { + return_code |= 1; + cout << endl; + cerr << "Query error:" << endl; + cerr << " * " << e.backtrace("\n * ") << e.message() << endl; + cerr << endl; + } + } + + if (mask_reasons_to_explain.any()) + { + cout << colour(cl_heading, "Key to mask reasons:") << endl << endl; + + /* use for/case to get compiler warnings when new mr_ are added */ + for (MaskReason m(MaskReason(0)) ; m < last_mr ; + m = MaskReason(static_cast<int>(m) + 1)) + { + if (! mask_reasons_to_explain.test(m)) + continue; + + switch (m) + { + case mr_keyword: + cout << "* " << colour(cl_masked, "K") << ": keyword"; + break; + case mr_user_mask: + cout << "* " << colour(cl_masked, "U") << ": user mask"; + break; + case mr_profile_mask: + cout << "* " << colour(cl_masked, "P") << ": profile mask"; + break; + case mr_repository_mask: + cout << "* " << colour(cl_masked, "R") << ": repository mask"; + break; + case mr_eapi: + cout << "* " << colour(cl_masked, "E") << ": EAPI"; + break; + case mr_license: + cout << "* " << colour(cl_masked, "L") << ": licence"; + break; + case mr_by_association: + cout << "* " << colour(cl_masked, "A") << ": by association"; + break; + + case last_mr: + break; + } + + cout << endl; + } + + cout << endl; + } + + return return_code; +} + diff --git a/0.8.0/src/paludis/query.hh b/0.8.0/src/paludis/query.hh new file mode 100644 index 000000000..62e7e0283 --- /dev/null +++ b/0.8.0/src/paludis/query.hh @@ -0,0 +1,32 @@ +/* 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_SRC_QUERY_HH +#define PALUDIS_GUARD_SRC_QUERY_HH 1 + +#include "command_line.hh" + +/** \file + * Declaration for the do_query function. + */ + +/// Handle --query. +int do_query(); + +#endif diff --git a/0.8.0/src/paludis/sync.cc b/0.8.0/src/paludis/sync.cc new file mode 100644 index 000000000..89f08ebe8 --- /dev/null +++ b/0.8.0/src/paludis/sync.cc @@ -0,0 +1,129 @@ +/* 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 "colour.hh" +#include "sync.hh" +#include <paludis/tasks/sync_task.hh> +#include <paludis/environment/default/default_environment.hh> +#include <paludis/syncer.hh> +#include <iomanip> +#include <iostream> +#include <string> + +/** \file + * Handle the --sync action for the main paludis program. + */ + +using namespace paludis; +using std::cerr; +using std::cout; +using std::endl; + +namespace +{ + class OurSyncTask : + public SyncTask + { + private: + int _return_code; + + public: + OurSyncTask() : + SyncTask(DefaultEnvironment::get_instance()), + _return_code(0) + { + } + + virtual void on_sync_all_pre(); + virtual void on_sync_pre(const RepositoryName &); + virtual void on_sync_post(const RepositoryName &); + virtual void on_sync_skip(const RepositoryName &); + virtual void on_sync_fail(const RepositoryName &, const SyncFailedError &); + virtual void on_sync_succeed(const RepositoryName &); + virtual void on_sync_all_post(); + + int return_code() const + { + return _return_code; + } + }; + + void + OurSyncTask::on_sync_all_pre() + { + } + + void + OurSyncTask::on_sync_pre(const RepositoryName & r) + { + cout << colour(cl_heading, "Sync " + stringify(r)) << endl; + cerr << xterm_title("Syncing " + stringify(r)); + } + + void + OurSyncTask::on_sync_post(const RepositoryName &) + { + } + + void + OurSyncTask::on_sync_skip(const RepositoryName & r) + { + cout << "Sync " << r << " skipped" << endl; + } + + void + OurSyncTask::on_sync_succeed(const RepositoryName & r) + { + cout << "Sync " << r << " completed" << endl; + } + + void + OurSyncTask::on_sync_fail(const RepositoryName & r, const SyncFailedError & e) + { + _return_code |= 1; + cout << endl; + cerr << "Sync error:" << endl; + cerr << " * " << e.backtrace("\n * ") << e.message() << endl; + cerr << endl; + cout << "Sync " << r << " failed" << endl; + } + + void + OurSyncTask::on_sync_all_post() + { + cout << endl; + } +} + +int do_sync() +{ + Context context("When performing sync action from command line:"); + + OurSyncTask task; + + for (CommandLine::ParametersIterator q(CommandLine::get_instance()->begin_parameters()), + q_end(CommandLine::get_instance()->end_parameters()) ; q != q_end ; ++q) + task.add_target(*q); + + task.execute(); + + return task.return_code(); +} + + diff --git a/0.8.0/src/paludis/sync.hh b/0.8.0/src/paludis/sync.hh new file mode 100644 index 000000000..92c518cd9 --- /dev/null +++ b/0.8.0/src/paludis/sync.hh @@ -0,0 +1,33 @@ +/* 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_SRC_SYNC_HH +#define PALUDIS_GUARD_SRC_SYNC_HH 1 + +#include "command_line.hh" + +/** \file + * Declaration for the do_sync function. + */ + +/// Handle --sync. +int do_sync(); + +#endif + diff --git a/0.8.0/src/paludis/uninstall.cc b/0.8.0/src/paludis/uninstall.cc new file mode 100644 index 000000000..b34268a45 --- /dev/null +++ b/0.8.0/src/paludis/uninstall.cc @@ -0,0 +1,185 @@ +/* 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 "colour.hh" +#include "uninstall.hh" + +#include <paludis/environment/default/default_environment.hh> +#include <paludis/tasks/uninstall_task.hh> + +#include <iostream> + +/** \file + * Handle the --uninstall action for the main paludis program. + */ + +using namespace paludis; + +using std::cerr; +using std::cout; +using std::endl; + +namespace +{ + class OurUninstallTask : + public UninstallTask + { + private: + int _count, _current_count; + + public: + OurUninstallTask() : + UninstallTask(DefaultEnvironment::get_instance()), + _count(0), + _current_count(0) + { + }; + + virtual void on_build_unmergelist_pre() + { + cout << "Building unmerge list... " << std::flush; + } + + virtual void on_build_unmergelist_post() + { + cout << "done" << endl; + } + + virtual void on_display_unmerge_list_pre() + { + cout << endl << colour(cl_heading, "These packages will be uninstalled:") + << endl << endl; + } + + virtual void on_display_unmerge_list_post() + { + cout << endl << endl << + "Total: " << _count << (_count == 1 ? " package" : " packages") << endl; + } + + virtual void on_display_unmerge_list_entry(const PackageDatabaseEntry & d) + { + cout << "* " << colour(cl_package_name, stringify(d)) << endl; + ++_count; + } + + virtual void on_uninstall_all_pre() + { + } + + virtual void on_uninstall_pre(const PackageDatabaseEntry & d) + { + cout << endl << colour(cl_heading, "Uninstalling " + + stringify(d.name) + "-" + stringify(d.version) + + "::" + stringify(d.repository)) << endl << endl; + + cerr << xterm_title("(" + stringify(++_current_count) + " of " + + stringify(_count) + ") Uninstalling " + + stringify(d.name) + "-" + stringify(d.version) + + "::" + stringify(d.repository)); + } + + virtual void on_uninstall_post(const PackageDatabaseEntry &) + { + } + + virtual void on_uninstall_all_post() + { + } + + virtual void on_update_world_pre() + { + cout << endl << colour(cl_heading, "Updating world file") << endl << endl; + } + + virtual void on_update_world(const PackageDepAtom & a) + { + cout << "* removing " << colour(cl_package_name, a.package()) << endl; + } + + virtual void on_update_world_post() + { + cout << endl; + } + + virtual void on_preserve_world() + { + cout << endl << colour(cl_heading, "Updating world file") << endl << endl; + cout << "* --preserve-world was specified, skipping world changes" << endl; + cout << endl; + } + }; +} + +int +do_uninstall() +{ + int return_code(0); + + Context context("When performing uninstall action from command line:"); + + OurUninstallTask task; + + task.set_pretend(CommandLine::get_instance()->a_pretend.specified()); + task.set_no_config_protect(CommandLine::get_instance()->a_no_config_protection.specified()); + task.set_preserve_world(CommandLine::get_instance()->a_preserve_world.specified()); + + try + { + for (CommandLine::ParametersIterator q(CommandLine::get_instance()->begin_parameters()), + q_end(CommandLine::get_instance()->end_parameters()) ; q != q_end ; ++q) + task.add_target(*q); + + task.execute(); + + cout << endl; + } + catch (const AmbiguousUnmergeTargetError & e) + { + cout << endl; + cerr << "Query error:" << endl; + cerr << " * " << e.backtrace("\n * "); + cerr << "Ambiguous unmerge target '" << e.target() << "'. Did you mean:" << endl; + for (AmbiguousUnmergeTargetError::Iterator o(e.begin()), + o_end(e.end()) ; o != o_end ; ++o) + cerr << " * =" << colour(cl_package_name, *o) << endl; + cerr << endl; + return 1; + } + catch (const PackageUninstallActionError & e) + { + cout << endl; + cerr << "Uninstall error:" << endl; + cerr << " * " << e.backtrace("\n * "); + cerr << e.message() << 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; + } + + return return_code; +} + diff --git a/0.8.0/src/paludis/uninstall.hh b/0.8.0/src/paludis/uninstall.hh new file mode 100644 index 000000000..a2a49ff78 --- /dev/null +++ b/0.8.0/src/paludis/uninstall.hh @@ -0,0 +1,33 @@ +/* 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_SRC_UNINSTALL_HH +#define PALUDIS_GUARD_SRC_UNINSTALL_HH 1 + +#include "command_line.hh" + +/** \file + * Declaration for the do_uninstall function. + */ + +/// Handle --uninstall. +int do_uninstall(); + +#endif + diff --git a/0.8.0/src/paludis/upgrade_TEST b/0.8.0/src/paludis/upgrade_TEST new file mode 100755 index 000000000..48b315fe3 --- /dev/null +++ b/0.8.0/src/paludis/upgrade_TEST @@ -0,0 +1,17 @@ +#!/bin/bash + +PALUDIS_HOME=./upgrade_TEST_dir/config/ \ + ./paludis --config-suffix upgrade-test --install =test-category/target-1 || exit 1 + +./upgrade_TEST_dir/root/usr/bin/testbin | grep testbin-1 >/dev/null || exit 1 +./upgrade_TEST_dir/root/usr/bin/testbin1 | grep testbin1 >/dev/null || exit 1 +./upgrade_TEST_dir/root/usr/bin/testbin2 && exit 1 + + +PALUDIS_HOME=./upgrade_TEST_dir/config/ \ + ./paludis --config-suffix upgrade-test --install target || exit 1 + +./upgrade_TEST_dir/root/usr/bin/testbin | grep testbin-2 >/dev/null || exit 1 +./upgrade_TEST_dir/root/usr/bin/testbin1 && exit 1 +./upgrade_TEST_dir/root/usr/bin/testbin2 | grep testbin2 >/dev/null || exit 1 + diff --git a/0.8.0/src/paludis/upgrade_TEST_cleanup.sh b/0.8.0/src/paludis/upgrade_TEST_cleanup.sh new file mode 100755 index 000000000..bc42e7885 --- /dev/null +++ b/0.8.0/src/paludis/upgrade_TEST_cleanup.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# vim: set ft=sh sw=4 sts=4 et : + +if [ -d upgrade_TEST_dir ] ; then + rm -fr upgrade_TEST_dir +else + true +fi + + + diff --git a/0.8.0/src/paludis/upgrade_TEST_setup.sh b/0.8.0/src/paludis/upgrade_TEST_setup.sh new file mode 100755 index 000000000..52e695815 --- /dev/null +++ b/0.8.0/src/paludis/upgrade_TEST_setup.sh @@ -0,0 +1,153 @@ +#!/bin/bash +# vim: set ft=sh sw=4 sts=4 et : + +mkdir upgrade_TEST_dir || exit 1 +cd upgrade_TEST_dir || exit 1 + +mkdir -p config/.paludis-upgrade-test +cat <<END > config/.paludis-upgrade-test/specpath +root = `pwd`/root +config-suffix = +END + +mkdir -p root/${SYSCONFDIR}/paludis/repositories +cat <<END > root/${SYSCONFDIR}/paludis/use.conf +* foo +END + +cat <<END > root/${SYSCONFDIR}/paludis/licenses.conf +* * +END + +cat <<END > root/${SYSCONFDIR}/paludis/keywords.conf +* test +END + +cat <<END > root/${SYSCONFDIR}/paludis/bashrc +export CHOST="my-chost" +export USER_BASHRC_WAS_USED=yes +END + +cat <<END > root/${SYSCONFDIR}/paludis/repositories/repo1.conf +location = `pwd`/repo1 +cache = /var/empty +format = portage +profiles = \${location}/profiles/testprofile +buildroot = `pwd`/build +END + +cat <<END > root/${SYSCONFDIR}/paludis/repositories/installed.conf +location = \${ROOT}/var/db/pkg +format = vdb +buildroot = `pwd`/build +END + +mkdir -p root/tmp +touch root/${SYSCONFDIR}/ld.so.conf +mkdir -p root/var/db/pkg + +mkdir -p repo1/{eclass,distfiles,profiles/testprofile,test-category/target/files} || exit 1 + +mkdir -p src/target-1 +cat <<"END" > src/target-1/testbin +#!/bin/bash +echo "This is testbin-1" +END +chmod +x src/target-1/testbin +cat <<"END" > src/target-1/testbin1 +#!/bin/bash +echo "This is testbin1" +END +chmod +x src/target-1/testbin1 +cd src +tar zcf target-1.tar.gz target-1/ +mv target-1.tar.gz ../repo1/distfiles/ +cd .. +rm -fr src + +mkdir -p src/target-2 +cat <<"END" > src/target-2/testbin +#!/bin/bash +echo "This is testbin-2" +END +chmod +x src/target-2/testbin +cat <<"END" > src/target-2/testbin2 +#!/bin/bash +echo "This is testbin2" +END +chmod +x src/target-2/testbin2 +cd src +tar zcf target-2.tar.gz target-2/ +mv target-2.tar.gz ../repo1/distfiles/ +cd .. +rm -fr src + +cd repo1 || exit 1 +echo "test-repo-1" > profiles/repo_name || exit 1 +cat <<END > profiles/categories || exit 1 +test-category +END +cat <<END > profiles/testprofile/make.defaults +ARCH=test +USERLAND=test +KERNEL=test +END + +cat <<"END" > eclass/myeclass.eclass || exit 1 +the_eclass_works() +{ + true +} +END + +cat <<"END" > test-category/target/target-1.ebuild || exit 1 +inherit myeclass + +DESCRIPTION="Test target" +HOMEPAGE="http://paludis.berlios.de/" +SRC_URI="http://invalid.domain/${P}.tar.gz" +SLOT="0" +IUSE="" +LICENSE="GPL-2" +KEYWORDS="test" + +pkg_setup() { + export VAR1=yes + VAR2=yes + local VAR3=yes +} + +src_install() { + [[ "${VAR1}" == yes ]] || die + [[ "${VAR2}" == yes ]] || die + [[ "${VAR3}" == yes ]] && die + + dobin testbin + dobin testbin${PV} +} + +pkg_prerm() { + [[ "${VAR1}" == yes ]] || die + [[ "${VAR2}" == yes ]] || die + [[ "${VAR3}" == yes ]] && die + + the_eclass_works || die +} +END + +cat <<"END" > test-category/target/target-2.ebuild || exit 1 +DESCRIPTION="Test target" +HOMEPAGE="http://paludis.berlios.de/" +SRC_URI="http://invalid.domain/${P}.tar.gz" +SLOT="0" +IUSE="" +LICENSE="GPL-2" +KEYWORDS="test" + +src_install() { + dobin testbin + dobin testbin${PV} +} +END +cd .. + diff --git a/0.8.0/src/paludis/use.cc b/0.8.0/src/paludis/use.cc new file mode 100644 index 000000000..f598e48f8 --- /dev/null +++ b/0.8.0/src/paludis/use.cc @@ -0,0 +1,125 @@ +/* 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 "use.hh" +#include "colour.hh" +#include <paludis/util/tokeniser.hh> +#include <sstream> +#include <set> + +using namespace paludis; + +namespace +{ + std::string::size_type + use_expand_delim_pos(const UseFlagName & u, const UseFlagNameCollection::ConstPointer c) + { + for (UseFlagNameCollection::Iterator i(c->begin()), i_end(c->end()) ; i != i_end ; ++i) + if (0 == u.data().compare(0, i->data().length(), i->data(), 0, i->data().length())) + return i->data().length(); + return std::string::npos; + } +} + +std::string +make_pretty_use_flags_string(const Environment * const env, const PackageDatabaseEntry & p, + VersionMetadata::ConstPointer metadata, const PackageDatabaseEntry * const other_p) +{ + std::ostringstream c; + + if (metadata->get_ebuild_interface()) + { + const RepositoryUseInterface * const use_interface( + env->package_database()-> + fetch_repository(p.repository)->use_interface); + std::set<UseFlagName> iuse; + WhitespaceTokeniser::get_instance()->tokenise( + metadata->get_ebuild_interface()->iuse, + create_inserter<UseFlagName>(std::inserter(iuse, iuse.end()))); + + /* display normal use flags first */ + for (std::set<UseFlagName>::const_iterator i(iuse.begin()), i_end(iuse.end()) ; + i != i_end ; ++i) + { + if (std::string::npos != use_expand_delim_pos(*i, use_interface->use_expand_prefixes())) + continue; + + if (env->query_use(*i, &p)) + { + if (use_interface && use_interface->query_use_force(*i, &p)) + c << " " << colour(cl_flag_on, "(" + stringify(*i) + ")"); + else + c << " " << colour(cl_flag_on, *i); + } + else + { + if (use_interface && use_interface->query_use_mask(*i, &p)) + c << " " << colour(cl_flag_off, "(-" + stringify(*i) + ")"); + else + c << " " << colour(cl_flag_off, "-" + stringify(*i)); + } + + if (other_p) + if (env->query_use(*i, &p) != env->query_use(*i, other_p)) + c << "*"; + } + + /* now display expand flags */ + UseFlagName old_expand_name("OFTEN_NOT_BEEN_ON_BOATS"); + for (std::set<UseFlagName>::const_iterator i(iuse.begin()), i_end(iuse.end()) ; + i != i_end ; ++i) + { + std::string::size_type delim_pos; + if (std::string::npos == ((delim_pos = use_expand_delim_pos(*i, use_interface->use_expand_prefixes())))) + continue; + if (use_interface->use_expand_hidden_prefixes()->count(UseFlagName(i->data().substr(0, delim_pos)))) + continue; + + UseFlagName expand_name(i->data().substr(0, delim_pos)), expand_value(i->data().substr(delim_pos + 1)); + + if (expand_name != old_expand_name) + { + c << " " << expand_name << ":"; + old_expand_name = expand_name; + } + + if (env->query_use(*i, &p)) + { + if (use_interface && use_interface->query_use_force(*i, &p)) + c << " " << colour(cl_flag_on, "(" + stringify(expand_value) + ")"); + else + c << " " << colour(cl_flag_on, expand_value); + } + else + { + if (use_interface && use_interface->query_use_mask(*i, &p)) + c << " " << colour(cl_flag_off, "(-" + stringify(expand_value) + ")"); + else + c << " " << colour(cl_flag_off, "-" + stringify(expand_value)); + } + + if (other_p) + if (env->query_use(*i, &p) != env->query_use(*i, other_p)) + c << "*"; + } + } + + return c.str(); +} + diff --git a/0.8.0/src/paludis/use.hh b/0.8.0/src/paludis/use.hh new file mode 100644 index 000000000..ed7e84607 --- /dev/null +++ b/0.8.0/src/paludis/use.hh @@ -0,0 +1,36 @@ +/* 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_SRC_PALUDIS_USE_HH +#define PALUDIS_GUARD_SRC_PALUDIS_USE_HH 1 + +#include <paludis/name.hh> +#include <paludis/environment.hh> +#include <paludis/package_database_entry.hh> +#include <paludis/version_metadata.hh> + +/** + * Make a nice string for outputting USE flags. + */ +std::string +make_pretty_use_flags_string(const paludis::Environment * const env, const paludis::PackageDatabaseEntry & p, + paludis::VersionMetadata::ConstPointer metadata, const paludis::PackageDatabaseEntry * const other_p = 0) + PALUDIS_ATTRIBUTE((nonnull(1))); + +#endif diff --git a/0.8.0/src/paludis/version_TEST b/0.8.0/src/paludis/version_TEST new file mode 100755 index 000000000..02513f03a --- /dev/null +++ b/0.8.0/src/paludis/version_TEST @@ -0,0 +1,3 @@ +#!/bin/bash + +PALUDIS_SKIP_CONFIG=yes ./paludis --version diff --git a/0.8.0/src/qualudis/Makefile.am b/0.8.0/src/qualudis/Makefile.am new file mode 100644 index 000000000..7157136af --- /dev/null +++ b/0.8.0/src/qualudis/Makefile.am @@ -0,0 +1,63 @@ +AM_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src @PALUDIS_CXXFLAGS@ +DEFS= \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DBIGTEMPDIR=\"/var/tmp\" +SUBDIRS = . + +man_pages = qualudis.1 + +if ENABLE_QA + +bin_PROGRAMS = qualudis +noinst_PROGRAMS = man-qualudis +man_MANS = $(man_pages) + +qualudis_SOURCES = \ + qualudis_command_line.hh qualudis_command_line.cc \ + qualudis.cc + +qualudis_LDADD = \ + $(top_builddir)/paludis/qa/libpaludisqa.la \ + $(top_builddir)/paludis/libpaludis.la \ + $(top_builddir)/paludis/args/libpaludisargs.la \ + $(top_builddir)/paludis/util/libpaludisutil.la \ + $(top_builddir)/src/libcolour.a \ + $(PCREPLUSPLUS_LIBS) \ + $(LIBXML2DEPS_LIBS) \ + $(DYNAMIC_LD_LIBS) + +INCLUDES = $(PCREPLUSPLUS_CFLAGS) $(LIBXML2DEPS_CFLAGS) + +TESTS_ENVIRONMENT = env \ + TEST_SCRIPT_DIR="$(srcdir)/" \ + PALUDIS_REPOSITORY_SO_DIR="$(top_builddir)/paludis/repositories" \ + PALUDIS_NO_XTERM_TITLES="yes" \ + bash $(top_srcdir)/test/run_test.sh bash + +TESTS = version_TEST + +version_TEST : + echo -e "#!/bin/sh\n./qualudis --version" > $@ + +endif + +qualudis.1 : man-qualudis + ./man-qualudis | tee $@ | sed -e 's/^/ /' + +man_qualudis_SOURCES = \ + man_qualudis.cc \ + qualudis_command_line.hh \ + qualudis_command_line.cc + +man_qualudis_LDADD = \ + $(top_builddir)/paludis/args/libpaludisargs.la \ + $(top_builddir)/paludis/util/libpaludisutil.la \ + $(top_builddir)/src/libcolour.a \ + $(DYNAMIC_LD_LIBS) + +CLEANFILES = *~ version_TEST gmon.out *.gcov *.gcno *.gcda +DISTCLEANFILES = $(man_pages) +MAINTAINERCLEANFILES = Makefile.in +EXTRA_DIST = $(man_pages) + diff --git a/0.8.0/src/qualudis/man_qualudis.cc b/0.8.0/src/qualudis/man_qualudis.cc new file mode 100644 index 000000000..4f0f1f882 --- /dev/null +++ b/0.8.0/src/qualudis/man_qualudis.cc @@ -0,0 +1,37 @@ +/* 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 "qualudis_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, QualudisCommandLine::get_instance()); + return EXIT_SUCCESS; +} + + diff --git a/0.8.0/src/qualudis/qualudis.cc b/0.8.0/src/qualudis/qualudis.cc new file mode 100644 index 000000000..82f3a2ee6 --- /dev/null +++ b/0.8.0/src/qualudis/qualudis.cc @@ -0,0 +1,624 @@ +/* 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/args/args.hh> +#include <paludis/paludis.hh> +#include <paludis/qa/qa.hh> +#include <paludis/util/join.hh> +#include <paludis/util/dir_iterator.hh> +#include <paludis/util/log.hh> +#include <paludis/util/is_file_with_extension.hh> +#include <paludis/util/strip.hh> + +#include <cstdlib> +#include <iostream> +#include <algorithm> + +#include <libebt/libebt.hh> +#include <libwrapiter/libwrapiter.hh> + +#include "qualudis_command_line.hh" +#include "colour.hh" +#include "config.h" + +using namespace paludis; +using std::cout; +using std::cerr; +using std::endl; + +namespace +{ + struct DoHelp + { + const std::string message; + + DoHelp(const std::string & m = "") : + message(m) + { + } + }; + + struct DoVersion + { + }; + + void + display_header(const qa::CheckResult & r) + { + cout << r.item() << ": " << r.rule() << ":" << endl; + } + + void + display_header_once(bool * const once, const qa::CheckResult & r) + { + if (! *once) + { + display_header(r); + *once = true; + } + } + + void + display_no_errors(const qa::CheckResult & r) + { + if (QualudisCommandLine::get_instance()->a_verbose.specified()) + display_header(r); + } + + void + display_errors(const qa::CheckResult & r) + { + bool done_out(false); + + for (qa::CheckResult::Iterator i(r.begin()), i_end(r.end()) ; i != i_end ; ++i) + { + if (i->level < QualudisCommandLine::get_instance()->message_level) + continue; + + bool show(true); + do + { + switch (i->level) + { + case qa::qal_info: + display_header_once(&done_out, r); + cout << " info: "; + continue; + + case qa::qal_skip: + if (QualudisCommandLine::get_instance()->a_verbose.specified()) + { + display_header_once(&done_out, r); + cout << " skip: "; + } + else + show = false; + continue; + + case qa::qal_minor: + display_header_once(&done_out, r); + cout << " minor: "; + continue; + + case qa::qal_major: + display_header_once(&done_out, r); + cout << " major: "; + continue; + + case qa::qal_fatal: + display_header_once(&done_out, r); + cout << " fatal: "; + continue; + + case qa::qal_maybe: + display_header_once(&done_out, r); + cout << " maybe: "; + continue; + } + + throw InternalError(PALUDIS_HERE, "Bad mk_level"); + } + while (false); + + if (show) + cout << i->msg << endl; + } + } + + template <typename VC_> + struct IsImportant : + std::binary_function<bool, std::string, std::string> + { + bool operator() (const std::string & k1, const std::string & k2) const + { + return (*VC_::get_instance()->find_maker(k1))()->is_important() > + (*VC_::get_instance()->find_maker(k2))()->is_important(); + } + }; + + template <typename VC_, typename P_> + void do_check_kind(bool & ok, bool & fatal, const P_ & value) + { + std::list<std::string> checks; + VC_::get_instance()->copy_keys(std::back_inserter(checks)); + checks.sort(); + checks.sort(IsImportant<VC_>()); + + for (std::list<std::string>::const_iterator i(checks.begin()), + i_end(checks.end()) ; i != i_end ; ++i) + { + if (QualudisCommandLine::get_instance()->a_qa_checks.specified()) + if (QualudisCommandLine::get_instance()->a_qa_checks.args_end() == std::find( + QualudisCommandLine::get_instance()->a_qa_checks.args_begin(), + QualudisCommandLine::get_instance()->a_qa_checks.args_end(), + *i)) + continue; + + try + { + Context context("When performing check '" + stringify(*i) + "':"); + + qa::CheckResult r((*VC_::get_instance()->find_maker(*i)())(value)); + + if (r.empty()) + { + display_no_errors(r); + continue; + } + + display_errors(r); + + do + { + switch (r.most_severe_level()) + { + case qa::qal_info: + case qa::qal_skip: + case qa::qal_maybe: + continue; + + case qa::qal_minor: + case qa::qal_major: + ok = false; + continue; + + case qa::qal_fatal: + ok = false; + fatal = true; + return; + } + throw InternalError(PALUDIS_HERE, "Bad most_severe_level"); + } while (0); + } + catch (const InternalError &) + { + throw; + } + catch (const Exception & e) + { + std::cout << "Eek! Caught Exception '" << e.message() << "' (" << e.what() + << ") when doing check '" << *i << "'" << endl; + ok = false; + } + catch (const std::exception & e) + { + std::cout << "Eek! Caught std::exception '" << e.what() + << "' when doing check '" << *i << "'" << endl; + ok = false; + } + } + } + + bool + do_check_package_dir(const FSEntry & dir, const Environment & env) + { + Context context("When checking package '" + stringify(dir) + "':"); + cerr << xterm_title("Checking " + dir.dirname().basename() + "/" + + dir.basename() + " - qualudis"); + + bool ok(true), fatal(false); + + cout << "QA checks for package directory " << dir << ":" << endl; + + if (! fatal) + do_check_kind<qa::PackageDirCheckMaker>(ok, fatal, dir); + + if (! fatal) + { + std::list<FSEntry> files((DirIterator(dir)), DirIterator()); + for (std::list<FSEntry>::iterator f(files.begin()) ; f != files.end() ; ++f) + { + if (f->basename() == "CVS" || '.' == f->basename().at(0)) + continue; + if (fatal) + break; + + do_check_kind<qa::FileCheckMaker>(ok, fatal, *f); + } + } + + if (! fatal) + { + std::list<FSEntry> files((DirIterator(dir)), DirIterator()); + for (std::list<FSEntry>::iterator f(files.begin()) ; f != files.end() ; ++f) + { + if (! IsFileWithExtension(".ebuild")(*f)) + continue; + + qa::EbuildCheckData d( + QualifiedPackageName(CategoryNamePart(stringify(dir.dirname().basename())), + PackageNamePart(stringify(dir.basename()))), + VersionSpec(strip_leading_string(strip_trailing_string(f->basename(), ".ebuild"), + stringify(dir.basename()) + "-")), + &env); + do_check_kind<qa::EbuildCheckMaker>(ok, fatal, d); + + if (fatal) + break; + } + } + + if (! ok && (dir / "metadata.xml").is_regular_file()) + { + cout << "metadata.xml:" << endl; + qa::MetadataFile metadata(dir / "metadata.xml"); + if (metadata.end_herds() != metadata.begin_herds()) + cout << " herds: " << join(metadata.begin_herds(), metadata.end_herds(), ", ") << endl; + if (metadata.end_maintainers() != metadata.begin_maintainers()) + for (qa::MetadataFile::MaintainersIterator i(metadata.begin_maintainers()), + i_end(metadata.end_maintainers()) ; i != i_end ; ++i) + { + if (i->first.empty() && i->second.empty()) + continue; + + cout << " maintainer: "; + if (i->first.empty()) + cout << i->second; + else if (i->second.empty()) + cout << "<" << i->first << ">"; + else + cout << i->second << " <" << i->first << ">"; + cout << endl; + } + } + cout << endl; + + return ok; + } + + bool + do_check_category_dir(const FSEntry & dir, const Environment & env) + { + Context context("When checking category '" + stringify(dir) + "':"); + + cerr << xterm_title("Checking " + dir.basename() + " - qualudis"); + + cout << "QA checks for category directory " << dir << ":" << endl; + cout << endl; + + bool ok(true); + + for (DirIterator d(dir) ; d != DirIterator() ; ++d) + { + if ("CVS" == d->basename()) + continue; + else if ('.' == d->basename().at(0)) + continue; + else if (d->is_directory()) + ok &= do_check_package_dir(*d, env); + else if ("metadata.xml" == d->basename()) + { + bool fatal(false); + + cout << "QA checks for category file " << *d << ":" << endl; + + do_check_kind<qa::FileCheckMaker>(ok, fatal, *d); + + cout << endl; + + if (fatal) + break; + } + } + + return ok; + } + + bool + do_check_eclass_dir(const FSEntry & dir, const Environment &) + { + Context context("When checking eclass directory '" + stringify(dir) + "':"); + + cerr << xterm_title("Checking " + dir.basename() + " - qualudis"); + + cout << "QA checks for eclass directory " << dir << ":" << endl; + cout << endl; + + bool ok(true); + + for (DirIterator d(dir) ; d != DirIterator() ; ++d) + { + if ("CVS" == d->basename()) + continue; + else if ('.' == d->basename().at(0)) + continue; + else if (IsFileWithExtension(".eclass")(d->basename())) + { + bool fatal(false); + + cout << "QA checks for eclass file " << *d << ":" << endl; + + do_check_kind<qa::FileCheckMaker>(ok, fatal, *d); + + cout << endl; + + if (fatal) + break; + } + } + + return ok; + } + + bool + do_check_top_level(const FSEntry & dir) + { + Context context("When checking top level '" + stringify(dir) + "':"); + + cout << "QA checks for top level directory " << dir << ":" << endl << endl; + + qa::QAEnvironment env(dir); + bool ok(true); + + for (DirIterator d(dir) ; d != DirIterator() ; ++d) + { + if (d->basename() == "CVS" || '.' == d->basename().at(0)) + continue; + if (! d->is_directory()) + continue; + if (d->basename() == "eclass") + ok &= do_check_eclass_dir(*d, env); + else if (env.package_database()->fetch_repository( + env.package_database()->favourite_repository())-> + has_category_named(CategoryNamePart(d->basename()))) + ok &= do_check_category_dir(*d, env); + } + + return ok; + } + + + bool + do_check(const FSEntry & dir) + { + Context context("When checking directory '" + stringify(dir) + "':"); + + if (dir.basename() == "eclass" && dir.is_directory()) + { + qa::QAEnvironment env(dir.dirname()); + return do_check_eclass_dir(dir, env); + } + + else if (std::count_if(DirIterator(dir), DirIterator(), IsFileWithExtension( + dir.basename() + "-", ".ebuild"))) + { + qa::QAEnvironment env(dir.dirname().dirname()); + return do_check_package_dir(dir, env); + } + + else if ((dir / "profiles").is_directory()) + return do_check_top_level(dir); + + else if ((dir.dirname() / "profiles").is_directory()) + { + qa::QAEnvironment env(dir.dirname()); + return do_check_category_dir(dir, env); + } + + else + throw DoHelp("qualudis should be run inside a repository"); + } +} + +int main(int argc, char *argv[]) +{ + Context context("In main program:"); + + try + { + QualudisCommandLine::get_instance()->run(argc, argv); + + if (QualudisCommandLine::get_instance()->a_help.specified()) + throw DoHelp(); + + if (! QualudisCommandLine::get_instance()->a_log_level.specified()) + Log::get_instance()->set_log_level(ll_qa); + else if (QualudisCommandLine::get_instance()->a_log_level.argument() == "debug") + Log::get_instance()->set_log_level(ll_debug); + else if (QualudisCommandLine::get_instance()->a_log_level.argument() == "qa") + Log::get_instance()->set_log_level(ll_qa); + else if (QualudisCommandLine::get_instance()->a_log_level.argument() == "warning") + Log::get_instance()->set_log_level(ll_warning); + else if (QualudisCommandLine::get_instance()->a_log_level.argument() == "silent") + Log::get_instance()->set_log_level(ll_silent); + else + throw DoHelp("bad value for --log-level"); + + if (! QualudisCommandLine::get_instance()->a_message_level.specified()) + QualudisCommandLine::get_instance()->message_level = qa::qal_info; + else if (QualudisCommandLine::get_instance()->a_message_level.argument() == "info") + QualudisCommandLine::get_instance()->message_level = qa::qal_info; + else if (QualudisCommandLine::get_instance()->a_message_level.argument() == "minor") + QualudisCommandLine::get_instance()->message_level = qa::qal_minor; + else if (QualudisCommandLine::get_instance()->a_message_level.argument() == "major") + QualudisCommandLine::get_instance()->message_level = qa::qal_major; + else if (QualudisCommandLine::get_instance()->a_message_level.argument() == "fatal") + QualudisCommandLine::get_instance()->message_level = qa::qal_fatal; + else + throw DoHelp("bad value for --message-level"); + + if (QualudisCommandLine::get_instance()->a_version.specified()) + throw DoVersion(); + + if (QualudisCommandLine::get_instance()->a_describe.specified()) + { + if (! QualudisCommandLine::get_instance()->empty()) + throw DoHelp("describe action takes no parameters"); + + cout << "Package directory checks:" << endl; + std::list<std::string> package_dir_checks; + qa::PackageDirCheckMaker::get_instance()->copy_keys(std::back_inserter(package_dir_checks)); + for (std::list<std::string>::const_iterator i(package_dir_checks.begin()), + i_end(package_dir_checks.end()) ; i != i_end ; ++i) + cout << " " << *i << ":" << endl << " " << + (*qa::PackageDirCheckMaker::get_instance()->find_maker(*i))()->describe() << endl; + cout << endl; + + cout << "File checks:" << endl; + std::list<std::string> file_checks; + qa::FileCheckMaker::get_instance()->copy_keys(std::back_inserter(file_checks)); + for (std::list<std::string>::const_iterator i(file_checks.begin()), + i_end(file_checks.end()) ; i != i_end ; ++i) + cout << " " << *i << ":" << endl << " " << + (*qa::FileCheckMaker::get_instance()->find_maker(*i))()->describe() << endl; + cout << endl; + + cout << "Ebuild checks:" << endl; + std::list<std::string> ebuild_checks; + qa::EbuildCheckMaker::get_instance()->copy_keys(std::back_inserter(ebuild_checks)); + for (std::list<std::string>::const_iterator i(ebuild_checks.begin()), + i_end(ebuild_checks.end()) ; i != i_end ; ++i) + cout << " " << *i << ":" << endl << " " << + (*qa::EbuildCheckMaker::get_instance()->find_maker(*i))()->describe() << endl; + cout << endl; + + return EXIT_SUCCESS; + } + + if (! QualudisCommandLine::get_instance()->empty()) + { + QualudisCommandLine *c1 = QualudisCommandLine::get_instance(); + QualudisCommandLine::ParametersIterator argit = c1->begin_parameters(), arge = c1->end_parameters(); + for ( ; argit != arge; ++argit ) + { + std::string arg = *argit; + try + { + do_check(FSEntry::cwd() / arg); + } + catch(const DirOpenError & e) + { + cout << e.message() << endl; + } + } + return EXIT_SUCCESS; + } + else + return do_check(FSEntry::cwd()) ? EXIT_SUCCESS : EXIT_FAILURE; + + throw InternalError(__PRETTY_FUNCTION__, "no action?"); + } + catch (const DoVersion &) + { + cout << "qualudis, 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 << *QualudisCommandLine::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/0.8.0/src/qualudis/qualudis_command_line.cc b/0.8.0/src/qualudis/qualudis_command_line.cc new file mode 100644 index 000000000..00e6eb58b --- /dev/null +++ b/0.8.0/src/qualudis/qualudis_command_line.cc @@ -0,0 +1,80 @@ +/* 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 "qualudis_command_line.hh" + +QualudisCommandLine::QualudisCommandLine() : + ArgsHandler(), + + action_args(this, "Actions", + "Selects which basic action to perform. Up to one action should " + "be specified. If no action is specified, the directories specifed " + "on the command line (or, if none, the current directory) are " + "checked."), + a_describe(&action_args, "describe", 'd', "Describe checks"), + a_version(&action_args, "version", 'V', "Display program version"), + a_help(&action_args, "help", 'h', "Display program help"), + + check_options(this, "Options for general checks", + "Options relevant for the --owner actions."), + a_qa_checks(&check_options, "qa-check", 'c', "Only perform given check."), + a_verbose(&check_options, "verbose", 'v', "Be verbose"), + a_log_level(&check_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_message_level(&check_options, "message-level", 'M', "Specify the message level", + paludis::args::EnumArg::EnumArgOptions("info", "Show info and upwards") + ("minor", "Show minor and upwards") + ("major", "Show major and upwards") + ("fatal", "Show only fatals"), + "info"), + + message_level(paludis::qa::qal_info) +{ + add_usage_line("[ options ] [ directories ... ]"); +} + +QualudisCommandLine::~QualudisCommandLine() +{ +} + +std::string +QualudisCommandLine::app_name() const +{ + return "qualudis"; +} + +std::string +QualudisCommandLine::app_synopsis() const +{ + return "A QA tool for ebuilds"; +} + +std::string +QualudisCommandLine::app_description() const +{ + return + "qualudis is a QA assistant for ebuilds and ebuild repositories. It checks for " + "many common and potential mistakes and displays a summary of its findings. It " + "can also be used to commit changes to a repository's VCS."; +} diff --git a/0.8.0/src/qualudis/qualudis_command_line.hh b/0.8.0/src/qualudis/qualudis_command_line.hh new file mode 100644 index 000000000..ed2c1afac --- /dev/null +++ b/0.8.0/src/qualudis/qualudis_command_line.hh @@ -0,0 +1,74 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +#ifndef PALUDIS_GUARD_SRC_QUALUDIS_QUALUDIS_COMMAND_LINE_HH +#define PALUDIS_GUARD_SRC_QUALUDIS_QUALUDIS_COMMAND_LINE_HH 1 + +#include <paludis/args/args.hh> +#include <paludis/qa/message.hh> +#include <paludis/util/instantiation_policy.hh> + +class QualudisCommandLine : + public paludis::args::ArgsHandler, + public paludis::InstantiationPolicy<QualudisCommandLine, paludis::instantiation_method::SingletonAsNeededTag> +{ + friend class paludis::InstantiationPolicy<QualudisCommandLine, paludis::instantiation_method::SingletonAsNeededTag>; + + private: + /// Constructor. + QualudisCommandLine(); + + /// Destructor. + ~QualudisCommandLine(); + + 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; + + /// --describe + paludis::args::SwitchArg a_describe; + + /// --version + paludis::args::SwitchArg a_version; + + /// --help + paludis::args::SwitchArg a_help; + + ///\} + + ///\name Check options + ///\{ + + /// Check options. + paludis::args::ArgsGroup check_options; + + /// --qa-checks + paludis::args::StringSetArg a_qa_checks; + + /// --verbose + paludis::args::SwitchArg a_verbose; + + /// --log-level + paludis::args::EnumArg a_log_level; + + /// --message-level + paludis::args::EnumArg a_message_level; + + paludis::qa::QALevel message_level; + + ///\} +}; + + +#endif |