diff options
-rw-r--r-- | doc/en/aptitude.xml | 18 | ||||
-rw-r--r-- | doc/en/manpage.xml | 57 | ||||
-rw-r--r-- | src/cmdline/cmdline_check_resolver.cc | 139 | ||||
-rw-r--r-- | src/cmdline/cmdline_prompt.cc | 10 | ||||
-rw-r--r-- | src/cmdline/cmdline_prompt.h | 6 | ||||
-rw-r--r-- | src/cmdline/cmdline_search.cc | 60 | ||||
-rw-r--r-- | src/cmdline/cmdline_search.h | 3 | ||||
-rw-r--r-- | src/cmdline/cmdline_upgrade.cc | 16 | ||||
-rw-r--r-- | src/main.cc | 11 |
9 files changed, 296 insertions, 24 deletions
diff --git a/doc/en/aptitude.xml b/doc/en/aptitude.xml index e0cfb200..f383fef6 100644 --- a/doc/en/aptitude.xml +++ b/doc/en/aptitude.xml @@ -9439,6 +9439,20 @@ iuAU wesnoth-data +930kB 0.8.7-1 0.8.8-1.0w </seg> </seglistitem> + <seglistitem id='configCmdLine-Disable-Columns'> + <seg><literal>Aptitude::CmdLine::Disable-Columns</literal></seg> + <seg><literal>false</literal></seg> + <seg> + If this option is enabled, the results of command-line + searches (performed via <literal>aptitude + search</literal>) will not be formatted into + fixed-width columns or truncated to the screen width. + This is equivalent to the <link + linkend='cmdlineOptionDisableColumns'><literal>--disable-columns</literal></link> + command-line option. + </seg> + </seglistitem> + <seglistitem id='configCmdLine-Download-Only'> <seg><literal>Aptitude::CmdLine::Download-Only</literal></seg> <seg><literal>false</literal></seg> @@ -9629,8 +9643,8 @@ iuAU wesnoth-data +930kB 0.8.7-1 0.8.8-1.0w <seg><literal>Aptitude::Safe-Resolver::No-New-Installs</literal></seg> <seg><literal>false</literal></seg> <seg> - If this option is enabled, then when the - <quote>safe</quote> dependency resolver has been + If this option is <literal>true</literal>, then when + the <quote>safe</quote> dependency resolver has been activated via <link linkend='cmdlineSafeResolver'><literal>--safe-resolver</literal></link>, the resolver will not be allowed to install packages diff --git a/doc/en/manpage.xml b/doc/en/manpage.xml index 157676b2..e3ae7046 100644 --- a/doc/en/manpage.xml +++ b/doc/en/manpage.xml @@ -830,7 +830,14 @@ i A texlive-latex-extra Conflicts textopo</screen> <listitem> <para> Downloads the <literal>.deb</literal> file for the given - package to the current directory. + package to the current directory. If a package name + contains a tilde character + (<quote><literal>~</literal></quote>) or a question mark + (<quote><literal>?</literal></quote>), it will be treated + as a search pattern and all the matching packages will be + downloaded (see the section <quote><link + linkend='secSearchPatterns'>Search Patterns</link></quote> + in the &aptitude; reference manual). </para> <para> @@ -999,6 +1006,48 @@ i A texlive-latex-extra Conflicts textopo</screen> </listitem> </varlistentry> + <varlistentry id='cmdlineOptionDisableColumns'> + <term><literal>--disable-columns</literal></term> + + <listitem> + <para> + This option causes <literal>aptitude search</literal> to + output its results without any special formatting. In + particular: normally &aptitude; will add whitespace or + truncate search results in an attempt to fit its results + into vertical <quote>columns</quote>. With this flag, + each line will be formed by replacing any format escapes + in the format string with the correponding text; column + widths will be ignored. + </para> + + <para> + For instance, the first few lines of output from <quote><literal>aptitude search -F '%p %V' --disable-columns libedataserver</literal></quote> might be: + </para> + + <screen>disksearch 1.2.1-3 +hp-search-mac 0.1.3 +libbsearch-ruby 1.5-5 +libbsearch-ruby1.8 1.5-5 +libclass-dbi-abstractsearch-perl 0.07-2 +libdbix-fulltextsearch-perl 0.73-10</screen> + + <para> + As in the above example, + <literal>--disable-columns</literal> is often useful in + combination with a custom display format set using the + command-line option <link + linkend='cmdlineOptionFormat'><literal>-F</literal></link>. + </para> + + <para> + This corresponds to the configuration option + <literal><link + linkend='configCmdLine-Disable-Columns'>Aptitude::CmdLine::Disable-Columns</link></literal>. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><literal>-D</literal>, <literal>--show-deps</literal></term> @@ -1051,6 +1100,12 @@ i A texlive-latex-extra Conflicts textopo</screen> </para> <para> + The command-line option <link + linkend='cmdlineOptionDisableColumns'><literal>--disable-columns</literal></link> + is often useful in combination with <literal>-F</literal>. + </para> + + <para> This corresponds to the configuration option <literal><link linkend='configCmdLine-Package-Display-Format'>Aptitude::CmdLine::Package-Display-Format</link></literal>. </para> </listitem> diff --git a/src/cmdline/cmdline_check_resolver.cc b/src/cmdline/cmdline_check_resolver.cc index 6a059ef2..04463602 100644 --- a/src/cmdline/cmdline_check_resolver.cc +++ b/src/cmdline/cmdline_check_resolver.cc @@ -1,6 +1,6 @@ // cmdline_check_resolver.cc // -// Copyright (C) 2005, 2007 Daniel Burrows +// Copyright (C) 2005, 2007-2008 Daniel Burrows // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -26,8 +26,134 @@ #include <apt-pkg/error.h> +#include <algorithm> +#include <iterator> + using namespace std; +namespace +{ + // Check that each real (non-virtual) package and real version are + // represented in the universe. + void check_packages_and_versions(const aptitude_universe &u) + { + std::set<pkgCache::PkgIterator> real_packages; + + // Insert each non-virtual package into real_packages. + for(pkgCache::PkgIterator pkg = (*apt_cache_file)->PkgBegin(); + !pkg.end(); ++pkg) + { + if(!pkg.VersionList().end()) + real_packages.insert(pkg); + } + + std::set<pkgCache::PkgIterator> seen_packages; + + for(aptitude_universe::package_iterator pi = u.packages_begin(); + !pi.end(); ++pi) + { + const aptitude_universe::package p = *pi; + const pkgCache::PkgIterator apt_pkg = p.get_pkg(); + bool seen_uninst = false; + + seen_packages.insert(apt_pkg); + + std::set<pkgCache::VerIterator> real_versions; + for(pkgCache::VerIterator ver = apt_pkg.VersionList(); + !ver.end(); ++ver) + { + // Skip versions that exist only on the current system and + // that have been removed; the resolver does. + if( ! (!ver.Downloadable() && + (ver != apt_pkg.CurrentVer() || + apt_pkg->CurrentState == pkgCache::State::ConfigFiles) )) + real_versions.insert(ver); + } + + std::set<pkgCache::VerIterator> seen_versions; + for(aptitude_universe::package::version_iterator vi = p.versions_begin(); + !vi.end(); ++vi) + { + if(vi.get_ver().end()) + seen_uninst = true; + else + seen_versions.insert(vi.get_ver()); + } + + if(!seen_uninst) + std::cout << "Didn't see the UNINST version of the package " << apt_pkg.Name() << "." << std::endl; + + std::vector<pkgCache::VerIterator> remaining_versions; + std::set_difference(real_versions.begin(), real_versions.end(), + seen_versions.begin(), seen_versions.end(), + std::back_inserter(remaining_versions)); + + for(std::vector<pkgCache::VerIterator>::const_iterator it = + remaining_versions.begin(); it != remaining_versions.end(); + ++it) + { + std::cout << "The package version " << it->ParentPkg().Name() + << " " << it->VerStr() << " is missing from the resolver." + << std::endl; + } + + if((*apt_cache_file)[apt_pkg].Keep() && + apt_pkg->CurrentState == pkgCache::State::ConfigFiles) + { + if(!p.current_version().get_ver().end()) + { + std::cout << "The package " << apt_pkg.Name() + << " only has config files installed, but version " + << p.current_version().get_ver().VerStr() + << " is installed according to the resolver." + << std::endl; + } + } + else + { + pkgCache::VerIterator cache_instver = (*apt_cache_file)[apt_pkg].InstVerIter(*apt_cache_file); + pkgCache::VerIterator resolver_instver = p.current_version().get_ver(); + + if(cache_instver != resolver_instver) + { + if(cache_instver.end()) + std::cout << "The package " << apt_pkg.Name() + << " should not be installed, but version " + << resolver_instver.VerStr() + << " is installed according to the resolver." + << std::endl; + else if(resolver_instver.end()) + std::cout << "The package " << apt_pkg.Name() + << " should be installed at version " + << cache_instver.VerStr() + << ", but it isn't installed according to the resolver." + << std::endl; + else + std::cout << "The package " << apt_pkg.Name() + << " should be installed at version " + << cache_instver.VerStr() + << ", but version " + << resolver_instver.VerStr() + << " is installed according to the resolver." + << std::endl; + } + } + } + + std::vector<pkgCache::PkgIterator> remaining_packages; + std::set_difference(real_packages.begin(), real_packages.end(), + seen_packages.begin(), seen_packages.end(), + std::back_inserter(remaining_packages)); + + for(std::vector<pkgCache::PkgIterator>::const_iterator it = + remaining_packages.begin(); it != remaining_packages.end(); ++it) + { + std::cout << "The package " << it->Name() + << " is missing from the resolver model." << std::endl; + } + } +} + int cmdline_check_resolver(int argc, char *argv[], const char *status_fname) { @@ -45,6 +171,17 @@ int cmdline_check_resolver(int argc, char *argv[], aptitude_universe u(*apt_cache_file); + std::cout << "Checking that packages and versions are properly projected." + << std::endl; + + check_packages_and_versions(u); + + // TODO: test that all dependencies are represented, somehow. This + // is complicated since dependency representation isn't one-to-one. + + std::cout << "Checking internal consistency of the dependency model." + << std::endl; + sanity_check_universe(u); std::cout << "Sanity check complete." << std::endl; diff --git a/src/cmdline/cmdline_prompt.cc b/src/cmdline/cmdline_prompt.cc index e536c4ff..398cddee 100644 --- a/src/cmdline/cmdline_prompt.cc +++ b/src/cmdline/cmdline_prompt.cc @@ -748,11 +748,11 @@ static bool prompt_trust() * user are being installed/removed (eg, because of sticky states) and * tell the caller to pause for confirmation. */ -static bool cmdline_show_preview(bool as_upgrade, pkgset &to_install, - pkgset &to_hold, pkgset &to_remove, - bool showvers, bool showdeps, - bool showsize, bool showwhy, - int verbose) +bool cmdline_show_preview(bool as_upgrade, pkgset &to_install, + pkgset &to_hold, pkgset &to_remove, + bool showvers, bool showdeps, + bool showsize, bool showwhy, + int verbose) { const int quiet = aptcfg->FindI("Quiet", 0); bool all_empty=true; diff --git a/src/cmdline/cmdline_prompt.h b/src/cmdline/cmdline_prompt.h index 653e6d44..f8ab58a8 100644 --- a/src/cmdline/cmdline_prompt.h +++ b/src/cmdline/cmdline_prompt.h @@ -70,6 +70,12 @@ bool cmdline_do_prompt(bool as_upgrade, pkgPolicy &policy, bool arch_only); +bool cmdline_show_preview(bool as_upgrade, pkgset &to_install, + pkgset &to_hold, pkgset &to_remove, + bool showvers, bool showdeps, + bool showsize, bool showwhy, + int verbose); + /** Prompt for a single line of input from the user. * * \param prompt a message to display before reading input. diff --git a/src/cmdline/cmdline_search.cc b/src/cmdline/cmdline_search.cc index 45bf3f5f..e76376c9 100644 --- a/src/cmdline/cmdline_search.cc +++ b/src/cmdline/cmdline_search.cc @@ -27,8 +27,9 @@ using namespace std; namespace cw = cwidget; using cwidget::util::transcode; using namespace aptitude::matching; +using namespace cwidget::config; -class search_result_parameters : public cwidget::config::column_parameters +class search_result_parameters : public column_parameters { pkg_match_result *r; public: @@ -91,7 +92,8 @@ public: // FIXME: apt-cache does lots of tricks to make this fast. Should I? int cmdline_search(int argc, char *argv[], const char *status_fname, - string display_format, string width, string sort) + string display_format, string width, string sort, + bool disable_columns) { int real_width=-1; @@ -123,7 +125,7 @@ int cmdline_search(int argc, char *argv[], const char *status_fname, return -1; } - cwidget::config::column_definition_list *columns = + column_definition_list *columns = parse_columns(wdisplay_format, pkg_item::pkg_columnizer::parse_column_type, pkg_item::pkg_columnizer::defaults); @@ -201,15 +203,53 @@ int cmdline_search(int argc, char *argv[], const char *status_fname, for(vector<pair<pkgCache::PkgIterator, pkg_match_result *> >::iterator i=output.begin(); i!=output.end(); ++i) { - cwidget::config::column_parameters *p = + column_parameters *p = new search_result_parameters(i->second); + pkg_item::pkg_columnizer columnizer(i->first, + i->first.VersionList(), + *columns, + 0); + if(disable_columns) + { + // Instantiate the format string without clipping or + // expanding columns. + // + // TODO: this should move into cwidget in the future, as a new + // mode of operation for layout_columns(). + std::wstring output; + + for(column_definition_list::iterator it = columns->begin(); + it != columns->end(); + ++it) + { + if(it->type == column_definition::COLUMN_LITERAL) + output += it->arg; + else + { + eassert(it->type == column_definition::COLUMN_GENERATED || + it->type == column_definition::COLUMN_PARAM); + + if(it->type == column_definition::COLUMN_GENERATED) + { + cwidget::column_disposition disp = columnizer.setup_column(it->ival); + output += disp.text; + } + else + { + if(p->param_count() <= it->ival) + output += L"###"; + else + output += p->get_param(it->ival); + } + } + } - printf("%ls\n", - pkg_item::pkg_columnizer(i->first, - i->first.VersionList(), - *columns, - 0).layout_columns(real_width==-1?screen_width:real_width, - *p).c_str()); + printf("%ls\n", output.c_str()); + } + else + printf("%ls\n", + columnizer.layout_columns(real_width==-1?screen_width:real_width, + *p).c_str()); // Note that this deletes the whole result, so we can't re-use // the list. diff --git a/src/cmdline/cmdline_search.h b/src/cmdline/cmdline_search.h index ead96a70..284f2601 100644 --- a/src/cmdline/cmdline_search.h +++ b/src/cmdline/cmdline_search.h @@ -11,6 +11,7 @@ */ int cmdline_search(int argc, char *argv[], const char *status_fname, - std::string display_format, std::string width, std::string sort); + std::string display_format, std::string width, std::string sort, + bool disable_columns); #endif // CMDLINE_SEARCH_H diff --git a/src/cmdline/cmdline_upgrade.cc b/src/cmdline/cmdline_upgrade.cc index 1cd679bd..c7bf5192 100644 --- a/src/cmdline/cmdline_upgrade.cc +++ b/src/cmdline/cmdline_upgrade.cc @@ -89,8 +89,20 @@ int cmdline_upgrade(int argc, char *argv[], // resolver. (*apt_cache_file)->mark_all_upgradable(false, true, NULL); - if(verbose > 0) - show_broken(); + if(verbose > 0 && (*apt_cache_file)->BrokenCount() > 0) + { + pkgset to_install, to_hold, to_remove; + cmdline_show_preview(true, + to_install, + to_hold, + to_remove, + showvers, + showdeps, + showsize, + showwhy, + verbose); + show_broken(); + } if(!aptitude::cmdline::safe_resolve_deps(verbose, no_new_installs, true)) { diff --git a/src/main.cc b/src/main.cc index f105d0eb..d4bd2107 100644 --- a/src/main.cc +++ b/src/main.cc @@ -207,7 +207,8 @@ enum { OPTION_SAFE_RESOLVER, OPTION_FULL_RESOLVER, OPTION_ARCH_ONLY, - OPTION_NOT_ARCH_ONLY + OPTION_NOT_ARCH_ONLY, + OPTION_DISABLE_COLUMNS }; int getopt_result; @@ -230,6 +231,7 @@ option opts[]={ {"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}, @@ -282,6 +284,7 @@ int main(int argc, char *argv[]) bool safe_resolver_no_new_installs = aptcfg->FindB(PACKAGE "::Safe-Resolver::No-New-Installs", false); bool safe_resolver_no_new_upgrades = aptcfg->FindB(PACKAGE "::Safe-Resolver::No-New-Upgrades", false); bool always_use_safe_resolver = aptcfg->FindB(PACKAGE "::Always-Use-Safe-Resolver", false); + bool disable_columns = aptcfg->FindB(PACKAGE "::CmdLine::Disable-Columns", false); bool safe_resolver_option = false; bool full_resolver_option = false; @@ -520,6 +523,9 @@ int main(int argc, char *argv[]) case OPTION_ARCH_ONLY: arch_only = true; break; + case OPTION_DISABLE_COLUMNS: + disable_columns = true; + break; default: fprintf(stderr, "%s", _("WEIRDNESS: unknown option code received\n")); @@ -599,7 +605,8 @@ int main(int argc, char *argv[]) return cmdline_search(argc-optind, argv+optind, status_fname, display_format, width, - sort_policy); + sort_policy, + disable_columns); else if(!strcasecmp(argv[optind], "why")) return cmdline_why(argc - optind, argv + optind, status_fname, verbose, false); |