aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-10-04 19:03:44 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-10-04 19:03:44 +0100
commit343898402c4d4ac9c7d5230d8ef05673782777c9 (patch)
tree2ca6838fdc9b0f25ecd93573f9083f4ff6348de3
parent829bee9a7628e6eed13e7830ff0491bb68139a9e (diff)
downloadpaludis-343898402c4d4ac9c7d5230d8ef05673782777c9.tar.gz
paludis-343898402c4d4ac9c7d5230d8ef05673782777c9.tar.xz
cave print-spec
Fixes: ticket:999
-rw-r--r--.gitignore1
-rw-r--r--src/clients/cave/Makefile.am2
-rw-r--r--src/clients/cave/cmd_print_spec.cc297
-rw-r--r--src/clients/cave/cmd_print_spec.hh43
-rw-r--r--src/clients/cave/command_factory.cc2
5 files changed, 345 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 813dc9d..0606842 100644
--- a/.gitignore
+++ b/.gitignore
@@ -115,6 +115,7 @@ paludis-*.*.*.tar.bz2
/doc/clients/cave-print-repository-metadata.html
/doc/clients/cave-print-set.html
/doc/clients/cave-print-sets.html
+/doc/clients/cave-print-spec.html
/doc/clients/cave-print-sync-protocols.html
/doc/clients/cave-purge.html
/doc/clients/cave-report.html
diff --git a/src/clients/cave/Makefile.am b/src/clients/cave/Makefile.am
index 57352e3..4a67b62 100644
--- a/src/clients/cave/Makefile.am
+++ b/src/clients/cave/Makefile.am
@@ -56,6 +56,7 @@ command_MANS = \
cave-print-repository-metadata.1 \
cave-print-set.1 \
cave-print-sets.1 \
+ cave-print-spec.1 \
cave-print-sync-protocols.1 \
cave-purge.1 \
cave-report.1 \
@@ -149,6 +150,7 @@ libcave_a_SOURCES = \
cmd_print_repository_metadata.cc cmd_print_repository_metadata.hh \
cmd_print_set.cc cmd_print_set.hh \
cmd_print_sets.cc cmd_print_sets.hh \
+ cmd_print_spec.cc cmd_print_spec.hh \
cmd_print_sync_protocols.cc cmd_print_sync_protocols.hh \
cmd_purge.cc cmd_purge.hh \
cmd_report.cc cmd_report.hh cmd_report-fmt.hh \
diff --git a/src/clients/cave/cmd_print_spec.cc b/src/clients/cave/cmd_print_spec.cc
new file mode 100644
index 0000000..8add403
--- /dev/null
+++ b/src/clients/cave/cmd_print_spec.cc
@@ -0,0 +1,297 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2010 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "cmd_print_spec.hh"
+#include "exceptions.hh"
+#include "format_string.hh"
+#include <paludis/args/args.hh>
+#include <paludis/args/do_help.hh>
+#include <paludis/util/simple_visitor_cast.hh>
+#include <paludis/util/set.hh>
+#include <paludis/util/iterator_funcs.hh>
+#include <paludis/util/options.hh>
+#include <paludis/util/map.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/make_null_shared_ptr.hh>
+#include <paludis/util/indirect_iterator-impl.hh>
+#include <paludis/util/join.hh>
+#include <paludis/util/make_named_values.hh>
+#include <paludis/environment.hh>
+#include <paludis/metadata_key.hh>
+#include <paludis/user_dep_spec.hh>
+#include <paludis/additional_package_dep_spec_requirement.hh>
+#include <paludis/partially_made_package_dep_spec.hh>
+#include <paludis/user_dep_spec.hh>
+#include <paludis/version_operator.hh>
+#include <paludis/version_requirements.hh>
+#include <iostream>
+#include <algorithm>
+
+#include "command_command_line.hh"
+
+using namespace paludis;
+using namespace cave;
+using std::cout;
+using std::endl;
+
+namespace
+{
+ struct PrintSpecCommandLine :
+ CaveCommandCommandLine
+ {
+ virtual std::string app_name() const
+ {
+ return "cave print-spec";
+ }
+
+ virtual std::string app_synopsis() const
+ {
+ return "Prints a dependency spec.";
+ }
+
+ virtual std::string app_description() const
+ {
+ return "Parses a dependency spec and prints it out, possibly after applying certain modifications. No "
+ "formatting is used, making the output suitable for parsing by scripts.";
+ }
+
+ args::ArgsGroup g_modifications;
+ args::StringArg a_package;
+ args::StringArg a_slot_requirement;
+ args::StringArg a_in_repository;
+ args::StringArg a_from_repository;
+ args::StringArg a_installable_to_repository;
+ args::StringArg a_installed_at_path;
+ args::StringArg a_installable_to_path;
+ args::StringArg a_package_part;
+ args::StringArg a_category_part;
+ args::StringSetArg a_version_requirement;
+ args::EnumArg a_version_requirements_mode;
+ args::StringSetArg a_additional_requirement;
+
+ PrintSpecCommandLine() :
+ g_modifications(main_options_section(), "Modification Options", "Options for modifying the spec. If an empty string is "
+ "specified for a modification, that requirement is removed."),
+ a_package(&g_modifications, "package", '\0', "Specify the cat/pkg requirement."),
+ a_slot_requirement(&g_modifications, "slot", '\0', "Specify the slot requirement."),
+ a_in_repository(&g_modifications, "in-repository", '\0', "Specify the in-repository requirement."),
+ a_from_repository(&g_modifications, "from-repository", '\0', "Specify the from-repository requirement."),
+ a_installable_to_repository(&g_modifications, "installable-to-repository", '\0', "Specify the installable-to-repository requirement."),
+ a_installed_at_path(&g_modifications, "installed-at-path", '\0', "Specify the installed-at-path requirement."),
+ a_installable_to_path(&g_modifications, "installable-to-path", '\0', "Specify the installable-to-path requirement."),
+ a_package_part(&g_modifications, "package-part", '\0', "Specify the /pkg requirement."),
+ a_category_part(&g_modifications, "category-part", '\0', "Specify the cat/ requirement."),
+ a_version_requirement(&g_modifications, "version-requirement", '\0', "Specify a version requirement. May be specified "
+ "multiple times. If specified at all, replaces all version requirements. Use a single empty string to remove "
+ "all version requirements."),
+ a_version_requirements_mode(&g_modifications, "version-requirements-mode", '\0', "Specify the mode of version requirements.",
+ args::EnumArg::EnumArgOptions
+ ("default", "Do not change the version requirements mode")
+ ("and", "And")
+ ("or", "Or"),
+ "default"),
+ a_additional_requirement(&g_modifications, "additional-requirement", '\0', "Specify an additional requirement. May be "
+ "specified multiple times.")
+ {
+ add_usage_line("spec");
+ }
+ };
+
+ void do_one_spec(
+ const PackageDepSpec & spec,
+ const PrintSpecCommandLine & cmdline
+ )
+ {
+ PartiallyMadePackageDepSpec s(spec);
+
+ if (cmdline.a_package.specified())
+ {
+ if (cmdline.a_package.argument().empty())
+ s.clear_package();
+ else
+ s.package(QualifiedPackageName(cmdline.a_package.argument()));
+ }
+
+ if (cmdline.a_slot_requirement.specified())
+ {
+ if (cmdline.a_slot_requirement.argument().empty())
+ s.clear_slot_requirement();
+ else
+ s.slot_requirement(std::make_shared<UserSlotExactRequirement>(SlotName(cmdline.a_slot_requirement.argument())));
+ }
+
+ if (cmdline.a_in_repository.specified())
+ {
+ if (cmdline.a_in_repository.argument().empty())
+ s.clear_in_repository();
+ else
+ s.in_repository(RepositoryName(cmdline.a_in_repository.argument()));
+ }
+
+ if (cmdline.a_from_repository.specified())
+ {
+ if (cmdline.a_from_repository.argument().empty())
+ s.clear_from_repository();
+ else
+ s.from_repository(RepositoryName(cmdline.a_from_repository.argument()));
+ }
+
+ if (cmdline.a_installable_to_repository.specified())
+ {
+ if (cmdline.a_installable_to_repository.argument().empty())
+ s.clear_installable_to_repository();
+ else
+ {
+ std::string repo(cmdline.a_installable_to_repository.argument());
+ bool include_masked(false);
+ if ('?' == repo.at(repo.length() - 1))
+ {
+ repo.erase(repo.length() - 1);
+ include_masked = true;
+ }
+
+ s.installable_to_repository(make_named_values<InstallableToRepository>(
+ n::include_masked() = include_masked,
+ n::repository() = RepositoryName(repo)
+ ));
+ }
+ }
+
+ if (cmdline.a_installed_at_path.specified())
+ {
+ if (cmdline.a_installed_at_path.argument().empty())
+ s.clear_installed_at_path();
+ else
+ s.installed_at_path(FSPath(cmdline.a_installed_at_path.argument()));
+ }
+
+ if (cmdline.a_installable_to_path.specified())
+ {
+ if (cmdline.a_installable_to_path.argument().empty())
+ s.clear_installable_to_path();
+ else
+ {
+ std::string path(cmdline.a_installable_to_path.argument());
+ bool include_masked(false);
+ if ('?' == path.at(path.length() - 1))
+ {
+ path.erase(path.length() - 1);
+ include_masked = true;
+ }
+
+ s.installable_to_path(make_named_values<InstallableToPath>(
+ n::include_masked() = include_masked,
+ n::path() = FSPath(path)
+ ));
+ }
+ }
+
+ if (cmdline.a_package_part.specified())
+ {
+ if (cmdline.a_package_part.argument().empty())
+ s.clear_package_name_part();
+ else
+ s.package_name_part(PackageNamePart(cmdline.a_package_part.argument()));
+ }
+
+ if (cmdline.a_category_part.specified())
+ {
+ if (cmdline.a_category_part.argument().empty())
+ s.clear_category_name_part();
+ else
+ s.category_name_part(CategoryNamePart(cmdline.a_category_part.argument()));
+ }
+
+ if (cmdline.a_version_requirement.specified())
+ {
+ s.clear_version_requirements();
+
+ for (args::StringSetArg::ConstIterator a(cmdline.a_version_requirement.begin_args()),
+ a_end(cmdline.a_version_requirement.end_args()) ;
+ a != a_end ; ++a)
+ if (! a->empty())
+ {
+ std::string::size_type p(a->find_first_not_of("=<>~"));
+ if (std::string::npos == p)
+ throw args::DoHelp("--" + cmdline.a_version_requirement.long_name() + " arguments should be in the form =1.23");
+
+ std::string op(a->substr(0, p)), ver(a->substr(p));
+
+ s.version_requirement(make_named_values<VersionRequirement>(
+ n::version_operator() = VersionOperator(op),
+ n::version_spec() = VersionSpec(ver, {})
+ ));
+ }
+ }
+
+ if (cmdline.a_version_requirements_mode.specified())
+ {
+ if (cmdline.a_version_requirements_mode.argument() == "and")
+ s.version_requirements_mode(vr_and);
+ else if (cmdline.a_version_requirements_mode.argument() == "or")
+ s.version_requirements_mode(vr_or);
+ else
+ throw args::DoHelp("Argument for --" + cmdline.a_version_requirements_mode.long_name() + " unrecognised");
+ }
+
+ if (cmdline.a_additional_requirement.specified())
+ {
+ s.clear_additional_requirements();
+
+ for (args::StringSetArg::ConstIterator a(cmdline.a_additional_requirement.begin_args()),
+ a_end(cmdline.a_additional_requirement.end_args()) ;
+ a != a_end ; ++a)
+ if (! a->empty())
+ s.additional_requirement(std::make_shared<UserKeyRequirement>(*a));
+ }
+
+ cout << PackageDepSpec(s) << endl;
+ }
+}
+
+int
+PrintSpecCommand::run(
+ const std::shared_ptr<Environment> & env,
+ const std::shared_ptr<const Sequence<std::string > > & args
+ )
+{
+ PrintSpecCommandLine cmdline;
+ cmdline.run(args, "CAVE", "CAVE_PRINT_SPEC_OPTIONS", "CAVE_PRINT_SPEC_CMDLINE");
+
+ if (cmdline.a_help.specified())
+ {
+ cout << cmdline;
+ return EXIT_SUCCESS;
+ }
+
+ if (1 != std::distance(cmdline.begin_parameters(), cmdline.end_parameters()))
+ throw args::DoHelp("print-spec takes exactly one parameter");
+
+ PackageDepSpec spec(parse_user_package_dep_spec(*cmdline.begin_parameters(), env.get(), { updso_allow_wildcards }));
+ do_one_spec(spec, cmdline);
+
+ return EXIT_SUCCESS;
+}
+
+std::shared_ptr<args::ArgsHandler>
+PrintSpecCommand::make_doc_cmdline()
+{
+ return std::make_shared<PrintSpecCommandLine>();
+}
+
diff --git a/src/clients/cave/cmd_print_spec.hh b/src/clients/cave/cmd_print_spec.hh
new file mode 100644
index 0000000..e614c4e
--- /dev/null
+++ b/src/clients/cave/cmd_print_spec.hh
@@ -0,0 +1,43 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2010 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_SRC_CLIENTS_CAVE_CMD_PRINT_SPEC_HH
+#define PALUDIS_GUARD_SRC_CLIENTS_CAVE_CMD_PRINT_SPEC_HH 1
+
+#include "command.hh"
+
+namespace paludis
+{
+ namespace cave
+ {
+ class PALUDIS_VISIBLE PrintSpecCommand :
+ public Command
+ {
+ public:
+ int run(
+ const std::shared_ptr<Environment> &,
+ const std::shared_ptr<const Sequence<std::string > > & args
+ );
+
+ std::shared_ptr<args::ArgsHandler> make_doc_cmdline();
+ };
+ }
+}
+
+#endif
diff --git a/src/clients/cave/command_factory.cc b/src/clients/cave/command_factory.cc
index 2df3968..8ae273f 100644
--- a/src/clients/cave/command_factory.cc
+++ b/src/clients/cave/command_factory.cc
@@ -69,6 +69,7 @@
#include "cmd_print_repository_metadata.hh"
#include "cmd_print_set.hh"
#include "cmd_print_sets.hh"
+#include "cmd_print_spec.hh"
#include "cmd_print_sync_protocols.hh"
#include "cmd_purge.hh"
#include "cmd_report.hh"
@@ -179,6 +180,7 @@ CommandFactory::CommandFactory() :
_imp->handlers.insert(std::make_pair("print-repository-metadata", std::bind(&make_command<PrintRepositoryMetadataCommand>)));
_imp->handlers.insert(std::make_pair("print-set", std::bind(&make_command<PrintSetCommand>)));
_imp->handlers.insert(std::make_pair("print-sets", std::bind(&make_command<PrintSetsCommand>)));
+ _imp->handlers.insert(std::make_pair("print-spec", std::bind(&make_command<PrintSpecCommand>)));
_imp->handlers.insert(std::make_pair("print-sync-protocols", std::bind(&make_command<PrintSyncProtocolsCommand>)));
_imp->handlers.insert(std::make_pair("report", std::bind(&make_command<ReportCommand>)));
_imp->handlers.insert(std::make_pair("resolve", std::bind(&make_command<ResolveCommand>)));