diff options
author | Daniel Hartwig <mandyke@gmail.com> | 2012-06-08 01:22:03 +0800 |
---|---|---|
committer | Daniel Hartwig <mandyke@gmail.com> | 2012-06-16 13:48:54 +0800 |
commit | d082e98fcf8d2809fd89d3bc2c3002f5e2e1f5a3 (patch) | |
tree | e2f728603afb6bc787e31c92b68d4cd3c5b63cef | |
parent | 6143ba98cf6c98a492e0fe9b247d42a2f95e4167 (diff) | |
download | aptitude-d082e98fcf8d2809fd89d3bc2c3002f5e2e1f5a3.tar.gz |
Use apt's CommandLine parser
Previously aptitude was using it's own command line
parser implemented on top of getopt. Replacing this
with the standard apt class means there are no longer
subtle quirks with our parser (such as "-qq" not
being valid, when it is fine for other apt programs).
The parser is closely tied to the Configuration, and
reads options directly in to the global apt config.
Some options were tracked independently of the global
config; this change is the first part rectifying that
situation. The goal is to keep all program options,
configuration state, etc. in the global config rather
than passing state variables between functions. Many
options which previously did not have an associated
configuration item now do; some remain undocumented
for now as they are transitional.
* handle "-qq" like other apt-utils
* properly process all -o command line options (Closes: #587671)
* unknown command line options trigger an error (Closes: #434502)
* --add-user-tag-to, --remove-user-tag-from are working;
no bug reports suggests that noone has noticed they
were broken
New aliases for some command-line options:
--yes, for --assume-yes (apt-get)
--default-release, for --target-release (apt-utils)
--install-on-startup, for -i
--update-on-startup, for -u
New configuration item:
Aptitude::CmdLine::Sorting, equivalent to --sort
Other new configuration items are for internal use only
at this point.
Closes: #587671
Closes: #434502
-rw-r--r-- | NEWS | 26 | ||||
-rw-r--r-- | doc/en/aptitude.xml | 19 | ||||
-rw-r--r-- | doc/en/manpage.xml | 22 | ||||
-rw-r--r-- | src/cmdline/cmdline_util.cc | 43 | ||||
-rw-r--r-- | src/cmdline/cmdline_util.h | 11 | ||||
-rw-r--r-- | src/main.cc | 747 |
6 files changed, 383 insertions, 485 deletions
@@ -11,11 +11,37 @@ Version 0.6.9 "All in a days work" Previously this would result in a "no such package" error. + * New aliases for some command-line options: + --yes, for --assume-yes (apt-get) + --default-release, for --target-release (apt-utils) + --install-on-startup, for -i + --update-on-startup, for -u + + * New configuration item: + Aptitude::CmdLine::Sorting, equivalent to --sort + +- Minor bugs: + + * handle "-qq" like other apt-utils + * properly process all -o command line options (Closes: #587671) + * unknown command line options trigger an error (Closes: #434502) + * --add-user-tag-to, --remove-user-tag-from are working; + no bug reports suggests that noone has noticed they + were broken, but they work now anyway + - Internal changes: * Unified the way packages are selected from command line arguments. + * Use apt's CommandLine parser + + Previously aptitude was using it's own command line + parser implemented on top of getopt. Replacing this + with the standard apt class means there are no longer + subtle quirks with our parser (such as "-qq" not + being valid when it is fine for other apt programs). + - Cosmetic and UI bugs: * [cmdline]: Use arch-qualified names for virtual packages in diff --git a/doc/en/aptitude.xml b/doc/en/aptitude.xml index d99ff4a8..cb673b39 100644 --- a/doc/en/aptitude.xml +++ b/doc/en/aptitude.xml @@ -11003,6 +11003,25 @@ e: Examine !: Apply .: Next ,: Previous</screen> </seg> </seglistitem> + <seglistitem id='configCmdLine-Sorting'> + <seg><literal>Aptitude::CmdLine::Sorting</literal></seg> + <seg><literal>name,version</literal></seg> + <seg> + Specify the order in which output from the <link + linkend='cmdlineSearch'><literal>search</literal></link> + and <link + linkend='cmdlineVersions'><literal>versions</literal></link> + commands should be displayed. For instance, passing + <quote><literal>installsize</literal></quote> for + <replaceable>order</replaceable> will list packages in + order according to their size when installed (see the + section <quote><link + linkend='secSortingPolicy'>Customizing how packages + are sorted</link></quote> in the &aptitude; reference + manual for more information). + </seg> + </seglistitem> + <seglistitem id='configCmdLine-Version-Display-Format'> <seg><literal>Aptitude::CmdLine::Version-Display-Format</literal></seg> <seg><literal>%c%a%M %p# %t %i</literal></seg> diff --git a/doc/en/manpage.xml b/doc/en/manpage.xml index 306640f5..28eeb68b 100644 --- a/doc/en/manpage.xml +++ b/doc/en/manpage.xml @@ -1604,6 +1604,11 @@ libdbix-fulltextsearch-perl 0.73-10</screen> <para> The default sort order is <literal>name,version</literal>. </para> + + <para> + Configuration Item: <literal><link + linkend='configCmdLine-Sorting'>Aptitude::CmdLine::Sorting</link></literal> + </para> </listitem> </varlistentry> @@ -2064,7 +2069,11 @@ Packages requiring libglib2.0-data: </varlistentry> <varlistentry> - <term><literal>-t</literal> <replaceable>release</replaceable>, <literal>--target-release</literal> <replaceable>release</replaceable></term> + <term> + <literal>-t</literal> <replaceable>release</replaceable>, + <literal>--target-release</literal> <replaceable>release</replaceable>, + <literal>--default-release</literal> <replaceable>release</replaceable> + </term> <listitem> <para> @@ -2204,7 +2213,10 @@ The following packages will be REMOVED: </varlistentry> <varlistentry> - <term><literal>-y</literal>, <literal>--assume-yes</literal></term> + <term> + <literal>-y</literal>, <literal>--yes</literal>, + <literal>--assume-yes</literal> + </term> <listitem> <para> @@ -2257,7 +2269,7 @@ The following packages will be REMOVED: <menuchoice><guimenu>Actions</guimenu><guimenuitem>Clean obsolete files</guimenuitem></menuchoice>). You cannot use this option and - <quote><literal>--autoclean-on-startup</literal></quote>, + <quote><literal>--clean-on-startup</literal></quote>, <quote><literal>-i</literal></quote>, or <quote><literal>-u</literal></quote> at the same time. </para> @@ -2283,7 +2295,7 @@ The following packages will be REMOVED: </varlistentry> <varlistentry> - <term><literal>-i</literal></term> + <term><literal>-i</literal>, <literal>--install-on-startup</literal></term> <listitem> <para> @@ -2310,7 +2322,7 @@ The following packages will be REMOVED: </varlistentry> <varlistentry> - <term><literal>-u</literal></term> + <term><literal>-u</literal>, <literal>--update-on-startup</literal></term> <listitem> <para> diff --git a/src/cmdline/cmdline_util.cc b/src/cmdline/cmdline_util.cc index bb0eb2fb..d7b1dcb4 100644 --- a/src/cmdline/cmdline_util.cc +++ b/src/cmdline/cmdline_util.cc @@ -732,6 +732,49 @@ namespace aptitude return rval; } + + bool read_user_tag_applications(std::vector<tag_application> &user_tags, + const char *config_item, + const bool is_add, const bool implicit) + { + const Configuration::Item *tree = aptcfg->Tree(config_item); + if(tree == NULL) + return true; + + for(Configuration::Item *item = tree->Child; + item != NULL; + item = item->Next) + { + if(implicit) + user_tags.push_back(tag_application(is_add, item->Value, NULL)); + else + { + const std::string arg(item->Value); + const std::string::size_type splitloc = arg.find(','); + if(splitloc == arg.npos) + return _error->Error(_("No comma following tag name \"%s\""), + arg.c_str()); + else + { + const std::string patternstr(arg, splitloc + 1); + const std::vector<const char *> terminators; + cwidget::util::ref_ptr<aptitude::matching::pattern> p = + aptitude::matching::parse(patternstr, + terminators, + true, + false); + if(p.valid() == false) + return false; + + const std::string tag(arg, 0, splitloc); + user_tags.push_back(tag_application(is_add, tag, p)); + } + } + } + + return true; + } + void apply_user_tags(const std::vector<tag_application> &user_tags) { using namespace matching; diff --git a/src/cmdline/cmdline_util.h b/src/cmdline/cmdline_util.h index e11722a4..2e10b005 100644 --- a/src/cmdline/cmdline_util.h +++ b/src/cmdline/cmdline_util.h @@ -222,6 +222,17 @@ namespace aptitude get_pattern() const { return pattern; } }; + /** \brief Read user-tag application requests from a configuration tree. + * + * \param user_tags The vector to which the applications will be added. + * \param config_item Name of the configuration item tree to read from. + * \param is_add \b true if these are add requests. + * \param implicit \b true if these are implicit requests. + */ + bool read_user_tag_applications(std::vector<tag_application> &user_tags, + const char *config_item, + const bool is_add, const bool implicit); + /** \brief Apply explicit and implicit user-tags to packages. * * Explicit tags are applied where their associated pattern holds; diff --git a/src/main.cc b/src/main.cc index 511715aa..e7007243 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,6 +1,7 @@ // main.cc (neƩ testscr.cc) // -// Copyright 1999-2011 Daniel Burrows +// Copyright (C) 1999-2011 Daniel Burrows +// Copyright (C) 2012 Daniel Hartwig // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -19,11 +20,6 @@ // // Tests the various screen-output mechanisms -#ifndef _GNU_SOURCE -#define _GNU_SOURCE // For getopt.h -#endif - -#include <getopt.h> #include <signal.h> #include "aptitude.h" @@ -79,6 +75,7 @@ #include <sigc++/functors/ptr_fun.h> #include <apt-pkg/error.h> +#include <apt-pkg/cmndline.h> #include <apt-pkg/init.h> #include <boost/format.hpp> @@ -259,100 +256,67 @@ static void usage() printf(_(" This aptitude does not have Super Cow Powers.\n")); } -// This handles options with no single-character equivalent -enum { - OPTION_VERSION = 1, - OPTION_VISUAL_PREVIEW, - OPTION_QUEUE_ONLY, - OPTION_PURGE_UNUSED, - OPTION_ALLOW_UNTRUSTED, - OPTION_NO_NEW_INSTALLS, - OPTION_NO_NEW_UPGRADES, - OPTION_ALLOW_NEW_INSTALLS, - OPTION_ALLOW_NEW_UPGRADES, - OPTION_ADD_USER_TAG, - OPTION_ADD_USER_TAG_TO, - OPTION_REMOVE_USER_TAG, - OPTION_REMOVE_USER_TAG_FROM, - OPTION_SAFE_RESOLVER, - OPTION_FULL_RESOLVER, - OPTION_SHOW_RESOLVER_ACTIONS, - OPTION_NO_SHOW_RESOLVER_ACTIONS, - OPTION_ARCH_ONLY, - OPTION_NOT_ARCH_ONLY, - OPTION_DISABLE_COLUMNS, - OPTION_GUI, - OPTION_NO_GUI, - OPTION_QT_GUI, - OPTION_NO_QT_GUI, - OPTION_LOG_LEVEL, - OPTION_LOG_FILE, - OPTION_LOG_CONFIG_FILE, - OPTION_LOG_RESOLVER, - OPTION_SHOW_SUMMARY, - OPTION_AUTOCLEAN_ON_STARTUP, - OPTION_CLEAN_ON_STARTUP, - OPTION_GROUP_BY, - OPTION_SHOW_PACKAGE_NAMES, - OPTION_NEW_GUI, -}; -int getopt_result; - -option opts[]={ - {"help", 0, NULL, 'h'}, - {"version", 0, &getopt_result, OPTION_VERSION}, - {"display-format", 1, NULL, 'F'}, - {"quiet", 2, NULL, 'q'}, - {"width", 1, NULL, 'w'}, - {"simulate", 0, NULL, 's'}, - {"allow-untrusted", 0, &getopt_result, OPTION_ALLOW_UNTRUSTED}, - {"with-recommends", 0, NULL, 'r'}, - {"without-recommends", 0, NULL, 'R'}, - {"download-only", 0, NULL, 'd'}, - {"assume-yes", 0, NULL, 'y'}, - {"verbose", 0, NULL, 'v'}, - {"show-versions", 0, NULL, 'V'}, - {"show-deps", 0, NULL, 'D'}, - {"show-why", 0, NULL, 'W'}, - {"prompt", 0, NULL, 'P'}, - {"sort", 1, NULL, 'O'}, - {"target-release", 1, NULL, 't'}, - {"disable-columns", 0, &getopt_result, OPTION_DISABLE_COLUMNS}, - {"no-new-installs", 0, &getopt_result, OPTION_NO_NEW_INSTALLS}, - {"no-new-upgrades", 0, &getopt_result, OPTION_NO_NEW_UPGRADES}, - {"allow-new-installs", 0, &getopt_result, OPTION_ALLOW_NEW_INSTALLS}, - {"allow-new-upgrades", 0, &getopt_result, OPTION_ALLOW_NEW_UPGRADES}, - {"safe-resolver", 0, &getopt_result, OPTION_SAFE_RESOLVER}, - {"full-resolver", 0, &getopt_result, OPTION_FULL_RESOLVER}, - {"show-resolver-actions", 0, &getopt_result, OPTION_SHOW_RESOLVER_ACTIONS}, - {"no-show-resolver-actions", 0, &getopt_result, OPTION_NO_SHOW_RESOLVER_ACTIONS}, - {"visual-preview", 0, &getopt_result, OPTION_VISUAL_PREVIEW}, - {"schedule-only", 0, &getopt_result, OPTION_QUEUE_ONLY}, - {"purge-unused", 0, &getopt_result, OPTION_PURGE_UNUSED}, - {"add-user-tag", 1, &getopt_result, OPTION_ADD_USER_TAG}, - {"add-user-tag-to", 1, &getopt_result, OPTION_ADD_USER_TAG_TO}, - {"remove-user-tag", 1, &getopt_result, OPTION_REMOVE_USER_TAG}, - {"remove-user-tag-from", 1, &getopt_result, OPTION_REMOVE_USER_TAG_FROM}, - {"arch-only", 0, &getopt_result, OPTION_ARCH_ONLY}, - {"not-arch-only", 0, &getopt_result, OPTION_NOT_ARCH_ONLY}, +CommandLine::Args opts[] = { + {'h', "help", "help", 0}, + {0, "version", "version", 0}, + {'q', "quiet", "quiet", CommandLine::IntLevel}, + {'F', "display-format", PACKAGE "::%::display-format", CommandLine::HasArg}, + {'w', "width", PACKAGE "::CmdLine::Package-Display-Width", CommandLine::HasArg}, + {'s', "simulate", PACKAGE "::Simulate", 0}, + {'r', "with-recommends", "APT::Install-Recommends", 0}, + {'R', "without-recommends", PACKAGE "::%::without-recommends", 0}, + {0, "allow-untrusted", PACKAGE "::CmdLine::Ignore-Trust-Violations", 0}, + {'d', "download-only", PACKAGE "::CmdLine::Download-Only", 0}, + {'y', "yes", PACKAGE "::CmdLine::Assume-Yes", 0}, + {'y', "assume-yes", PACKAGE "::CmdLine::Assume-Yes", 0}, + {'v', "verbose", PACKAGE "::CmdLine::Verbose", CommandLine::IntLevel}, + {'V', "show-versions", PACKAGE "::CmdLine::Show-Versions", 0}, + {'D', "show-deps", PACKAGE "::CmdLine::Show-Deps", 0}, + {'W', "show-why", PACKAGE "::CmdLine::Show-Why", 0}, + {'P', "prompt", PACKAGE "::CmdLine::Always-Prompt", 0}, + {'O', "sort", PACKAGE "::CmdLine::Sorting", CommandLine::HasArg}, + {'t', "target-release", "APT::Default-Release", CommandLine::HasArg}, + {'t', "default-release", "APT::Default-Release", CommandLine::HasArg}, + {0, "disable-columns", PACKAGE "::CmdLine::Disable-Columns", 0}, + {0, "no-new-installs", PACKAGE "::Safe-Resolver::No-New-Installs", 0}, + {0, "no-new-upgrades", PACKAGE "::Safe-Resolver::No-New-Upgrades", 0}, + {0, "allow-new-installs", PACKAGE "::Safe-Resolver::No-New-Installs", CommandLine::InvBoolean}, + {0, "allow-new-upgrades", PACKAGE "::Safe-Resolver::No-New-Upgrades", CommandLine::InvBoolean}, + {0, "safe-resolver", PACKAGE "::%::safe-resolver", CommandLine::Boolean}, + {0, "full-resolver", PACKAGE "::%::full-resolver", CommandLine::Boolean}, + {0, "show-resolver-actions", PACKAGE "::Safe-Resolver::Show-Resolver-Actions", 0}, + {0, "visual-preview", PACKAGE "::CmdLine::Visual-Preview", 0}, + {0, "schedule-only", PACKAGE "::CmdLine::Schedule-Only", 0}, + {0, "purge-unused", PACKAGE "::Purge-Unused", 0}, + {0, "add-user-tag", PACKAGE "::CmdLine::Add-User-Tag::", CommandLine::HasArg}, + {0, "remove-user-tag", PACKAGE "::CmdLine::Remove-User-Tag::", CommandLine::HasArg}, + {0, "add-user-tag-to", PACKAGE "::CmdLine::Add-User-Tag-To::", CommandLine::HasArg}, + {0, "remove-user-tag-from", PACKAGE "::CmdLine::Remove-User-Tag-From::", CommandLine::HasArg}, + {0, "arch-only", "APT::Get::Arch-Only", CommandLine::Boolean}, + {0, "not-arch-only", "APT::Get::Arch-Only", CommandLine::InvBoolean}, #ifdef HAVE_GTK - {"gui", 0, &getopt_result, OPTION_GUI}, + {0, "gui", PACKAGE "::%::start-gui", CommandLine::Boolean}, + {0, "new-gui", PACKAGE "::%::new-gui", 0}, #endif - {"no-gui", 0, &getopt_result, OPTION_NO_GUI}, + {0, "no-gui", PACKAGE "::%::start-gui", CommandLine::InvBoolean}, #ifdef HAVE_QT - {"qt", 0, &getopt_result, OPTION_QT_GUI}, - {"no-qt", 0, &getopt_result, OPTION_NO_QT_GUI}, + {0, "qt", PACKAGE "::%::qt-gui", 0}, #endif - {"log-level", 1, &getopt_result, OPTION_LOG_LEVEL}, - {"log-file", 1, &getopt_result, OPTION_LOG_FILE}, - {"log-config-file", 1, &getopt_result, OPTION_LOG_CONFIG_FILE}, - {"log-resolver", 0, &getopt_result, OPTION_LOG_RESOLVER}, - {"show-summary", 2, &getopt_result, OPTION_SHOW_SUMMARY}, - {"autoclean-on-startup", 0, &getopt_result, OPTION_AUTOCLEAN_ON_STARTUP}, - {"clean-on-startup", 0, &getopt_result, OPTION_CLEAN_ON_STARTUP}, - {"group-by", 1, &getopt_result, OPTION_GROUP_BY}, - {"show-package-names", 1, &getopt_result, OPTION_SHOW_PACKAGE_NAMES}, - {"new-gui", 0, &getopt_result, OPTION_NEW_GUI}, + {0, "log-level", PACKAGE "::Logging::Levels::", CommandLine::HasArg}, + {0, "log-file", PACKAGE "::Logging::File", CommandLine::HasArg}, + {0, "log-resolver", PACKAGE "::%::log-resolver", 0}, + {0, "show-summary", PACKAGE "::CmdLine::Show-Summary", CommandLine::HasArg}, + {0, "autoclean-on-startup", PACKAGE "::UI::Autoclean-On-Startup", 0}, + {0, "clean-on-startup", PACKAGE "::UI::Clean-On-Startup", 0}, + {'u', "update-on-startup", PACKAGE "::UI::Update-On-Startup", 0}, + {'i', "install-on-startup", PACKAGE "::UI::Install-On-Startup", 0}, + {0, "group-by", PACKAGE "::CmdLine::Versions-Group-By", CommandLine::HasArg}, + {0, "show-package-names", PACKAGE "::CmdLine::Versions-Show-Package-Names", CommandLine::HasArg}, + {'f', "fix-broken", PACKAGE "::CmdLine::Fix-Broken", 0}, + {'Z', "show-size-changes", PACKAGE "::CmdLine::Show-Size-Changes", 0}, + {'S', "pkgstates", PACKAGE "::%::pkgstates.in", CommandLine::HasArg}, + {'c', "config-file", 0, CommandLine::ConfigFile}, + {'o', "option", 0, CommandLine::ArbItem}, {0,0,0,0} }; @@ -505,6 +469,35 @@ namespace apply_logging_level(item->Value); } + /** \brief Read the default set of user tag application requests. */ + bool read_user_tag_applications(std::vector<aptitude::cmdline::tag_application> &user_tags) + { + struct tag_application_source + { + const char *config_item; + bool is_add; + bool implicit; + }; + + struct tag_application_source sources[] = { + {PACKAGE "::CmdLine::Add-User-Tag", true, true}, + {PACKAGE "::CmdLine::Remove-User-Tag", false, true}, + {PACKAGE "::CmdLine::Add-User-Tag-To", true, false}, + {PACKAGE "::CmdLine::Remove-User-Tag-From", false, false}, + {0,0,0} + }; + + using aptitude::cmdline::read_user_tag_applications; + for(size_t i = 0; sources[i].config_item != 0; ++i) + { + if(read_user_tag_applications(user_tags, sources[i].config_item, + sources[i].is_add, sources[i].implicit) == false) + return false; + } + + return true; + } + /** \brief Set some standard logging levels to output log * information about the resolver. * @@ -593,7 +586,7 @@ void handle_message_logged(const char *sourceFilename, } } -int main(int argc, char *argv[]) +int main(int argc, const char *argv[]) { // Block signals that we want to sigwait() on by default and put the // signal mask into a known state. This ensures that unless threads @@ -637,13 +630,85 @@ int main(int argc, char *argv[]) close_cache_on_exit close_on_exit; + // NOTE: this can of course be spoofed. Anyone bothering to is off their + // rocker. + argv0=argv[0]; + + // Backwards bug-compatibility; old versions used a misleading name + // for this option. + if(aptcfg->Find(PACKAGE "::Keep-Unused-Pattern", "") == "") + { + aptcfg->Set(PACKAGE "::Keep-Unused-Pattern", + aptcfg->Find(PACKAGE "::Delete-Unused-Pattern", "")); + aptcfg->Set(PACKAGE "::Delete-Unused-Pattern", ""); + } + else + aptcfg->Set(PACKAGE "::Delete-Unused-Pattern", ""); + + // By default don't log anything below WARN. + Logger::getLogger("")->setLevel(WARN_LEVEL); + + // HACK: Support for optional values in CommandLine. + for(int i = 1; i != argc; ++i) + { + if(strcasecmp("--show-summary", argv[i]) == 0) + argv[i] = strdup("--show-summary=first-package"); + } + + // Push existing errors so we can check for only option errors + // later. + _error->PushToStack(); + + // Parse the command line options. + CommandLine cmdl(opts, _config); + if(cmdl.Parse(argc, argv) == false) + { + _error->DumpErrors(); + return 1; + } + + if(aptcfg->FindB("help", false) == true) + { + usage(); + return 0; + } + + if(aptcfg->FindB("version", false) == true) + { + show_version(); + return 0; + } + + // HACK: Multiplexed arguments not supported by CommandLine. + { + string display_format = _config->Find(PACKAGE "::%::display-format", ""); + if(display_format.empty() == false) + { + _config->Set(PACKAGE "::CmdLine::Package-Display-Format", display_format); + _config->Set(PACKAGE "::CmdLine::Version-Display-Format", display_format); + } + + if(_config->FindB(PACKAGE "::%::without-recommends", false) == true) + { + _config->Set("APT::Install-Recommends", false); + _config->Set("APT::AutoRemove::Recommends-Important", true); + } + + if(_config->FindB(PACKAGE "::%::log-resolver", false) == true) + { + _config->Set(PACKAGE "::Logging::Levels::", "aptitude.resolver.search:trace"); + _config->Set(PACKAGE "::Logging::Levels::", "aptitude.resolver.search.costs:info"); + } + } + // The filename to read status information from. - char *status_fname=NULL; + string status_file = aptcfg->Find(PACKAGE "::%::pkgstates.in", ""); + char *status_fname = status_file.empty() ? NULL : strdup(status_file.c_str()); string package_display_format = aptcfg->Find(PACKAGE "::CmdLine::Package-Display-Format", "%c%a%M %p# - %d#"); string version_display_format = aptcfg->Find(PACKAGE "::CmdLine::Version-Display-Format", "%c%a%M %p# %t %i"); string group_by_mode_string = aptcfg->Find(PACKAGE "::CmdLine::Versions-Group-By", "auto"); string show_package_names_mode_string = aptcfg->Find(PACKAGE "::CmdLine::Versions-Show-Package-Names", "auto"); - string sort_policy="name,version"; + string sort_policy = aptcfg->Find(PACKAGE "::CmdLine::Sorting", "name,version"); string width=aptcfg->Find(PACKAGE "::CmdLine::Package-Display-Width", ""); // Set to a non-empty string to enable logging simplistically; set // to "-" to log to stdout. @@ -653,9 +718,11 @@ int main(int argc, char *argv[]) bool download_only=aptcfg->FindB(PACKAGE "::CmdLine::Download-Only", false);; bool arch_only = aptcfg->FindB("Apt::Get::Arch-Only", false); - bool update_only=false, install_only=false, queue_only=false; - bool autoclean_only = false; - bool clean_only = false; + bool update_only = aptcfg->FindB(PACKAGE "::UI::Update-On-Startup", false); + bool install_only = aptcfg->FindB(PACKAGE "::UI::Install-On-Startup", false); + bool queue_only = aptcfg->FindB(PACKAGE "::CmdLine::Schedule-Only", false); + bool autoclean_only = aptcfg->FindB(PACKAGE "::UI::Autoclean-On-Startup", false); + bool clean_only = aptcfg->FindB(PACKAGE "::UI::Clean-On-Startup", false); bool assume_yes=aptcfg->FindB(PACKAGE "::CmdLine::Assume-Yes", false); bool fix_broken=aptcfg->FindB(PACKAGE "::CmdLine::Fix-Broken", false); bool safe_resolver_no_new_installs = aptcfg->FindB(PACKAGE "::Safe-Resolver::No-New-Installs", false); @@ -665,6 +732,13 @@ int main(int argc, char *argv[]) resolver_mode_tp resolver_mode = resolver_mode_default; if(aptcfg->FindB(PACKAGE "::Always-Use-Safe-Resolver", false)) resolver_mode = resolver_mode_safe; + if(aptcfg->FindB(PACKAGE "::%::safe-resolver", false) == true + && aptcfg->FindB(PACKAGE "::%::full-resolver", false) == true) + _error->Error(_("Conflicting command line options --safe-resolver and --full-options")); + if(aptcfg->FindB(PACKAGE "::%::safe-resolver", false) == true) + resolver_mode = resolver_mode_safe; + if(aptcfg->FindB(PACKAGE "::%::full-resolver", false) == true) + resolver_mode = resolver_mode_full; bool disable_columns = aptcfg->FindB(PACKAGE "::CmdLine::Disable-Columns", false); @@ -676,320 +750,12 @@ int main(int argc, char *argv[]) bool visual_preview=aptcfg->FindB(PACKAGE "::CmdLine::Visual-Preview", false); bool always_prompt=aptcfg->FindB(PACKAGE "::CmdLine::Always-Prompt", false); int verbose=aptcfg->FindI(PACKAGE "::CmdLine::Verbose", 0); - bool seen_quiet = false; - int quiet = 0; - std::vector<aptitude::cmdline::tag_application> user_tags; - -#ifdef HAVE_GTK - // TODO: this should be a configuration option. - bool use_gtk_gui = aptcfg->FindB(PACKAGE "::Start-Gui", true); - // Use the in-progress new GUI harness instead of the old code. - bool use_new_gtk_gui = false; -#endif - -#ifdef HAVE_QT - // Use Qt frontend. - bool use_qt_gui = false; -#endif - - int curopt; - // The last option seen - // NOTE: this can of course be spoofed. Anyone bothering to is off their - // rocker. - argv0=argv[0]; - - // Backwards bug-compatibility; old versions used a misleading name - // for this option. - if(aptcfg->Find(PACKAGE "::Keep-Unused-Pattern", "") == "") + std::vector<aptitude::cmdline::tag_application> user_tags; + if(read_user_tag_applications(user_tags) == false) { - aptcfg->Set(PACKAGE "::Keep-Unused-Pattern", - aptcfg->Find(PACKAGE "::Delete-Unused-Pattern", "")); - aptcfg->Set(PACKAGE "::Delete-Unused-Pattern", ""); - } - else - aptcfg->Set(PACKAGE "::Delete-Unused-Pattern", ""); - - // By default don't log anything below WARN. - Logger::getLogger("")->setLevel(WARN_LEVEL); - - // Read the arguments: - while((curopt=getopt_long(argc, argv, "DVZWvhS:uiF:w:sO:fdyPt:q::Rro:", opts, NULL))!=-1) - { - switch(curopt) - { - case 'S': - status_fname=strdup(optarg); - break; - case 'h': - usage(); - exit(0); - case 'u': - update_only=true; - break; - case 'i': - install_only=true; - break; - case 'F': - package_display_format=optarg; - version_display_format = optarg; - break; - case 'w': - width=optarg; - break; - case 's': - simulate=true; - break; - case 'O': - sort_policy=optarg; - break; - case 'f': - fix_broken=true; - break; - case 'd': - download_only=true; - break; - case 'y': - assume_yes=true; - break; - case 'q': - if(optarg == 0) - ++quiet; - else - { - if(*optarg == '=') - ++optarg; - - if(*optarg == 0) - { - fprintf(stderr, _("Expected a number after -q=\n")); - return -1; - } - - char *tmp; - quiet = strtol(optarg, &tmp, 0); - - if(*tmp != '\0') - { - fprintf(stderr, _("Expected a number after -q=, got %s\n"), - optarg); - return -1; - } - } - seen_quiet = true; - break; - case 'r': - aptcfg->SetNoUser("Apt::Install-Recommends", "true"); - break; - case 'R': - aptcfg->SetNoUser("Apt::Install-Recommends", "false"); - aptcfg->SetNoUser("Apt::AutoRemove::RecommendsImportant", "true"); - break; - case 't': - aptcfg->SetNoUser("APT::Default-Release", optarg); - break; - case 'o': - { - string s=optarg; - string::size_type eqloc=s.find('='); - - // note that if eqloc!=s.npos, s.size()>0 - if(eqloc==s.npos || eqloc==s.size()-1) - fprintf(stderr, _("-o requires an argument of the form key=value, got %s\n"), optarg); - else - { - string key(s, 0, eqloc), value(s, eqloc+1); - - aptcfg->SetNoUser(key, value); - } - } - break; - case 'v': - ++verbose; - break; - case 'V': - showvers=true; - break; - case 'D': - showdeps=true; - break; - case 'Z': // ew - showsize=true; - break; - case 'W': - showwhy = true; - break; - case 'P': - always_prompt=true; - break; - case ':': - case '?': - usage(); - exit(1); - case 0: - switch(getopt_result) - { - case OPTION_VERSION: - show_version(); - exit(0); - case OPTION_ALLOW_UNTRUSTED: - aptcfg->Set(PACKAGE "::CmdLine::Ignore-Trust-Violations", true); - break; - case OPTION_SHOW_RESOLVER_ACTIONS: - safe_resolver_show_resolver_actions = true; - break; - case OPTION_NO_SHOW_RESOLVER_ACTIONS: - safe_resolver_show_resolver_actions = false; - break; - case OPTION_NO_NEW_INSTALLS: - safe_resolver_no_new_installs = true; - break; - case OPTION_ALLOW_NEW_INSTALLS: - safe_resolver_no_new_installs = false; - break; - case OPTION_NO_NEW_UPGRADES: - safe_resolver_no_new_upgrades = true; - break; - case OPTION_ALLOW_NEW_UPGRADES: - safe_resolver_no_new_upgrades = false; - break; - case OPTION_SAFE_RESOLVER: - resolver_mode = resolver_mode_safe; - break; - case OPTION_FULL_RESOLVER: - resolver_mode = resolver_mode_full; - break; - case OPTION_VISUAL_PREVIEW: - visual_preview=true; - break; - case OPTION_QUEUE_ONLY: - queue_only=true; - break; - case OPTION_PURGE_UNUSED: - aptcfg->Set(PACKAGE "::Purge-Unused", "true"); - break; - case OPTION_ADD_USER_TAG: - case OPTION_REMOVE_USER_TAG: - { - using aptitude::cmdline::tag_application; - const bool is_add = (getopt_result == OPTION_ADD_USER_TAG); - user_tags.push_back(tag_application(is_add, optarg, NULL)); - break; - } - case OPTION_ADD_USER_TAG_TO: - case OPTION_REMOVE_USER_TAG_FROM: - { - using aptitude::cmdline::tag_application; - const bool is_add = (getopt_result == OPTION_ADD_USER_TAG); - const std::string arg = optarg; - const std::string::size_type splitloc = arg.find(','); - if(splitloc == arg.npos) - { - fprintf(stderr, _("No comma following tag name \"%s\".\n"), arg.c_str()); - return -1; - } - else - { - const std::string patternstr(arg, splitloc + 1); - const std::vector<const char *> terminators; - cwidget::util::ref_ptr<aptitude::matching::pattern> p = - aptitude::matching::parse(patternstr, - terminators, - true, - false); - - if(!p.valid()) - { - _error->DumpErrors(); - return -1; - } - - user_tags.push_back(tag_application(is_add, optarg, p)); - } - } - case OPTION_NOT_ARCH_ONLY: - arch_only = false; - break; - case OPTION_ARCH_ONLY: - arch_only = true; - break; - case OPTION_DISABLE_COLUMNS: - disable_columns = true; - break; -#ifdef HAVE_GTK - case OPTION_GUI: - use_gtk_gui = true; - break; - case OPTION_NO_GUI: - use_gtk_gui = false; - break; -#else - case OPTION_NO_GUI: - // Recognize it as a NOP. - break; -#endif - case OPTION_LOG_LEVEL: - apply_logging_level(optarg); - break; - case OPTION_LOG_FILE: - log_file = optarg; - break; - case OPTION_LOG_RESOLVER: - enable_resolver_log(); - break; - - case OPTION_SHOW_SUMMARY: - if(optarg == NULL) - show_why_summary_mode = "first-package"; - else - show_why_summary_mode = optarg; - break; - - case OPTION_AUTOCLEAN_ON_STARTUP: - autoclean_only = true; - break; - - case OPTION_CLEAN_ON_STARTUP: - clean_only = true; - break; - - case OPTION_GROUP_BY: - group_by_mode_string = optarg; - break; - - case OPTION_SHOW_PACKAGE_NAMES: - show_package_names_mode_string = optarg; - break; - - case OPTION_NEW_GUI: -#ifdef HAVE_GTK - use_new_gtk_gui = true; -#endif - break; -#ifdef HAVE_QT - case OPTION_QT_GUI: - use_qt_gui = true; - break; - - case OPTION_NO_QT_GUI: - use_qt_gui = false; - break; -#endif - default: - fprintf(stderr, "%s", - _("WEIRDNESS: unknown option code received\n")); - break; - } - - getopt_result=0; - - break; - - default: - fprintf(stderr, "%s", - _("WEIRDNESS: unknown option code received\n")); - break; - } + _error->DumpErrors(); + return 1; } group_by_option group_by_mode; @@ -1052,15 +818,15 @@ int main(int argc, char *argv[]) const bool debug_search = aptcfg->FindB(PACKAGE "::CmdLine::Debug-Search", false); - int curr_quiet = aptcfg->FindI("quiet", 0); - if(seen_quiet) - aptcfg->SetNoUser("quiet", quiet); - if(quiet == 0 && !isatty(1)) - aptcfg->SetNoUser("quiet", std::max(curr_quiet, 1)); + if(!isatty(STDOUT_FILENO) && aptcfg->FindI("quiet", -1) == -1) + aptcfg->SetNoUser("quiet", 1); + int quiet = aptcfg->FindI("quiet"); if(simulate) aptcfg->SetNoUser(PACKAGE "::Simulate", true); + const bool cmdline_mode = cmdl.FileSize() > 0; + // Sanity-check { int num_startup_actions = 0; @@ -1082,7 +848,8 @@ int main(int argc, char *argv[]) } } - if((update_only || install_only || autoclean_only || clean_only) && optind != argc) + if((update_only || install_only || autoclean_only || clean_only) + && cmdline_mode == true) { fprintf(stderr, "%s\n", _("-u, -i, and --clean-on-startup may not be specified in command-line mode (eg, with 'install')")); @@ -1090,8 +857,17 @@ int main(int argc, char *argv[]) exit(1); } + // Abort now if there were any errors. + if(_error->PendingError() == true) + { + _error->DumpErrors(); + return 1; + } + + _error->MergeWithStack(); + // Possibly run off and do other commands. - if(optind!=argc) + if(cmdline_mode == true) { try { @@ -1107,27 +883,30 @@ int main(int argc, char *argv[]) exit(1); } + int filec = cmdl.FileSize(); + char **filev = const_cast<char **>(cmdl.FileList); + // TODO: warn the user if they passed --full-resolver to // something other than "upgrade" or do_action. - if(!strcasecmp(argv[optind], "update")) - return cmdline_update(argc-optind, argv+optind, verbose); - else if(!strcasecmp(argv[optind], "clean")) - return cmdline_clean(argc-optind, argv+optind, simulate); - else if(!strcasecmp(argv[optind], "autoclean")) - return cmdline_autoclean(argc-optind, argv+optind, simulate); - else if(!strcasecmp(argv[optind], "forget-new")) - return cmdline_forget_new(argc-optind, argv+optind, + if(!strcasecmp(filev[0], "update")) + return cmdline_update(filec, filev, verbose); + else if(!strcasecmp(filev[0], "clean")) + return cmdline_clean(filec, filev, simulate); + else if(!strcasecmp(filev[0], "autoclean")) + return cmdline_autoclean(filec, filev, simulate); + else if(!strcasecmp(filev[0], "forget-new")) + return cmdline_forget_new(filec, filev, status_fname, simulate); - else if(!strcasecmp(argv[optind], "search")) - return cmdline_search(argc-optind, argv+optind, + else if(!strcasecmp(filev[0], "search")) + return cmdline_search(filec, filev, status_fname, package_display_format, width, sort_policy, disable_columns, debug_search); - else if(!strcasecmp(argv[optind], "versions")) - return cmdline_versions(argc - optind, argv + optind, + else if(!strcasecmp(filev[0], "versions")) + return cmdline_versions(filec, filev, status_fname, version_display_format, width, sort_policy, @@ -1135,33 +914,33 @@ int main(int argc, char *argv[]) debug_search, group_by_mode, show_package_names_mode); - else if(!strcasecmp(argv[optind], "why")) - return cmdline_why(argc - optind, argv + optind, + else if(!strcasecmp(filev[0], "why")) + return cmdline_why(filec, filev, status_fname, verbose, why_display_mode, false); - else if(!strcasecmp(argv[optind], "why-not")) - return cmdline_why(argc - optind, argv + optind, + else if(!strcasecmp(filev[0], "why-not")) + return cmdline_why(filec, filev, status_fname, verbose, why_display_mode, true); - else if( (!strcasecmp(argv[optind], "install")) || - (!strcasecmp(argv[optind], "reinstall")) || - (!strcasecmp(argv[optind], "dist-upgrade")) || - (!strcasecmp(argv[optind], "full-upgrade")) || - (!strcasecmp(argv[optind], "safe-upgrade")) || - (!strcasecmp(argv[optind], "upgrade")) || - (!strcasecmp(argv[optind], "remove")) || - (!strcasecmp(argv[optind], "purge")) || - (!strcasecmp(argv[optind], "hold")) || - (!strcasecmp(argv[optind], "unhold")) || - (!strcasecmp(argv[optind], "markauto")) || - (!strcasecmp(argv[optind], "unmarkauto")) || - (!strcasecmp(argv[optind], "forbid-version")) || - (!strcasecmp(argv[optind], "keep")) || - (!strcasecmp(argv[optind], "keep-all")) || - (!strcasecmp(argv[optind], "build-dep")) || - (!strcasecmp(argv[optind], "build-depends"))) + else if( (!strcasecmp(filev[0], "install")) || + (!strcasecmp(filev[0], "reinstall")) || + (!strcasecmp(filev[0], "dist-upgrade")) || + (!strcasecmp(filev[0], "full-upgrade")) || + (!strcasecmp(filev[0], "safe-upgrade")) || + (!strcasecmp(filev[0], "upgrade")) || + (!strcasecmp(filev[0], "remove")) || + (!strcasecmp(filev[0], "purge")) || + (!strcasecmp(filev[0], "hold")) || + (!strcasecmp(filev[0], "unhold")) || + (!strcasecmp(filev[0], "markauto")) || + (!strcasecmp(filev[0], "unmarkauto")) || + (!strcasecmp(filev[0], "forbid-version")) || + (!strcasecmp(filev[0], "keep")) || + (!strcasecmp(filev[0], "keep-all")) || + (!strcasecmp(filev[0], "build-dep")) || + (!strcasecmp(filev[0], "build-depends"))) { - return cmdline_do_action(argc-optind, argv+optind, + return cmdline_do_action(filec, filev, status_fname, simulate, assume_yes, download_only, fix_broken, showvers, showdeps, @@ -1172,48 +951,56 @@ int main(int argc, char *argv[]) user_tags, arch_only, queue_only, verbose); } - else if(!strcasecmp(argv[optind], "add-user-tag") || - !strcasecmp(argv[optind], "remove-user-tag")) - return aptitude::cmdline::cmdline_user_tag(argc - optind, argv + optind, + else if(!strcasecmp(filev[0], "add-user-tag") || + !strcasecmp(filev[0], "remove-user-tag")) + return aptitude::cmdline::cmdline_user_tag(filec, filev, quiet, verbose); - else if(!strcasecmp(argv[optind], "extract-cache-subset")) - return aptitude::cmdline::extract_cache_subset(argc - optind, - argv + optind); - else if(!strcasecmp(argv[optind], "download")) - return cmdline_download(argc-optind, argv+optind); - else if(!strcasecmp(argv[optind], "changelog")) - return cmdline_changelog(argc-optind, argv+optind); - else if(!strcasecmp(argv[optind], "moo")) - return cmdline_moo(argc-optind, argv+optind, verbose); - else if(!strcasecmp(argv[optind], "show")) - return cmdline_show(argc-optind, argv+optind, verbose); - else if(!strcasecmp(argv[optind], "dump-resolver")) - return cmdline_dump_resolver(argc-optind, argv+optind, status_fname); - else if(!strcasecmp(argv[optind], "check-resolver")) - return cmdline_check_resolver(argc-optind, argv+optind, status_fname); - else if(!strcasecmp(argv[optind], "help")) + else if(!strcasecmp(filev[0], "extract-cache-subset")) + return aptitude::cmdline::extract_cache_subset(filec, + filev); + else if(!strcasecmp(filev[0], "download")) + return cmdline_download(filec, filev); + else if(!strcasecmp(filev[0], "changelog")) + return cmdline_changelog(filec, filev); + else if(!strcasecmp(filev[0], "moo")) + return cmdline_moo(filec, filev, verbose); + else if(!strcasecmp(filev[0], "show")) + return cmdline_show(filec, filev, verbose); + else if(!strcasecmp(filev[0], "dump-resolver")) + return cmdline_dump_resolver(filec, filev, status_fname); + else if(!strcasecmp(filev[0], "check-resolver")) + return cmdline_check_resolver(filec, filev, status_fname); + else if(!strcasecmp(filev[0], "help")) { usage(); exit(0); } // Debugging/profiling commands: - else if(!strcasecmp(argv[optind], "nop")) + else if(!strcasecmp(filev[0], "nop")) { OpTextProgress p(aptcfg->FindI("Quiet", 0)); _error->DumpErrors(); apt_init(&p, true); exit(0); } - else if(!strcasecmp(argv[optind], "nop-noselections")) + else if(!strcasecmp(filev[0], "nop-noselections")) { OpTextProgress p(aptcfg->FindI("Quiet", 0)); _error->DumpErrors(); apt_init(&p, false); exit(0); } + else if(!strcasecmp(filev[0], "dump-config")) + { + OpTextProgress p(aptcfg->FindI("Quiet", 0)); + apt_init(&p, false); + _config->Dump(std::cout); + _error->DumpErrors(); + exit(0); + } else { - fprintf(stderr, _("Unknown command \"%s\"\n"), argv[optind]); + fprintf(stderr, _("Unknown command \"%s\"\n"), filev[0]); usage(); exit(1); } @@ -1235,7 +1022,7 @@ int main(int argc, char *argv[]) } #ifdef HAVE_QT - if(use_qt_gui) + if(aptcfg->FindB(PACKAGE "::%::qt-gui", false) == true) { if(aptitude::gui::qt::main(argc, argv)) return 0; @@ -1247,9 +1034,9 @@ int main(int argc, char *argv[]) #endif #ifdef HAVE_GTK - if(use_gtk_gui) + if(aptcfg->FindB(PACKAGE "::%::start-gui", false) == true) { - if(use_new_gtk_gui) + if(aptcfg->FindB(PACKAGE "::%::new-gui", false) == true) { if(gui::init(argc, argv)) return 0; |