summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian PERRIER <bubulle@debian.org>2012-05-27 19:45:13 +0200
committerChristian PERRIER <bubulle@debian.org>2012-05-27 19:45:13 +0200
commit729b552c19ff1e11de38a485754284f629fdf076 (patch)
tree40619643fd092b18dbf16e495a642e90b3f4a844
parent3b96c07de4914ddf9b3fb8d4b3a34d1733effc65 (diff)
parent2d3ccf5faeeb59f1c3bb78710ffde0e4c0263fc7 (diff)
downloadaptitude-729b552c19ff1e11de38a485754284f629fdf076.tar.gz
Merge branch 'master' of ssh://git.debian.org/git/aptitude/aptitude
-rw-r--r--NEWS30
-rw-r--r--src/cmdline/cmdline_action.cc58
-rw-r--r--src/cmdline/cmdline_changelog.cc2
-rw-r--r--src/cmdline/cmdline_do_action.cc2
-rw-r--r--src/cmdline/cmdline_extract_cache_subset.cc5
-rw-r--r--src/cmdline/cmdline_simulate.cc2
-rw-r--r--src/cmdline/cmdline_update.cc2
-rw-r--r--src/cmdline/cmdline_user_tag.cc4
-rw-r--r--src/cmdline/cmdline_util.cc25
-rw-r--r--src/cmdline/cmdline_util.h6
-rw-r--r--src/cmdline/cmdline_versions.cc2
-rw-r--r--src/generic/apt/apt.cc4
-rw-r--r--src/generic/apt/download_update_manager.cc2
-rw-r--r--src/generic/apt/matching/match.cc2
-rw-r--r--src/generic/apt/pkg_changelog.cc2
-rw-r--r--src/generic/apt/tasks.cc292
-rw-r--r--src/generic/apt/tasks.h59
-rw-r--r--src/main.cc2
-rw-r--r--src/pkg_grouppolicy.cc44
-rw-r--r--src/pkg_info_screen.cc4
-rw-r--r--src/pkg_item.cc4
-rw-r--r--src/solution_fragment.cc2
-rw-r--r--src/ui.cc9
-rw-r--r--src/view_changelog.cc2
24 files changed, 422 insertions, 144 deletions
diff --git a/NEWS b/NEWS
index 6c812332..41952884 100644
--- a/NEWS
+++ b/NEWS
@@ -18,16 +18,46 @@ earlier releases.
files greater than several gigabytes in size -- using the
'unsigned long long' type to store the file size.
+ * [all]: Update to tasks support: task packages, multi-arch, syntax
+
+ Task packages (introduced with tasksel 3.0) are
+ meta-packages which define the dependencies of tasks. The
+ packages themselves have always worked but the 'tasks'
+ grouping policy and '?task' search term did not support
+ them. This update corrects for this.
+
+ As a result of this change to tasksel all Debian tasks now
+ function exactly like meta-packages. (Closes: #382631)
+
+ The syntax for installing tasks from the command line has
+ been updated. It now supports specifying an arch and
+ requires the same syntax as apt-utils ('^' must be the last
+ part of the name). Examples:
+
+ # aptitude install gnome-desktop^
+ # aptitude install ssh-server^:armel
+
+ This avoids ambiguity that may arise when a task and
+ package have the same name.
+
- Minor bugs:
* [all]: Changelog downloading is restored
(Closes: #669569, LP: #824708)
+ * [cmdline]: Exit with non-zero status when a package run is
+ aborted. (Closes: #293008)
+
- Cosmetic and UI bugs:
* [curses]: Adjust default widths of localized columns:
broken_count, downloadsize (Closes: #674045)
+ * [all]: Fold some near-duplicate strings
+
+ * [curses]: Update package views after 'Cancel pending actions'
+ (Closes: #595753)
+
- Documentation:
* [doc]: Add doctype headers to html docs.
diff --git a/src/cmdline/cmdline_action.cc b/src/cmdline/cmdline_action.cc
index e5c73938..a499d19a 100644
--- a/src/cmdline/cmdline_action.cc
+++ b/src/cmdline/cmdline_action.cc
@@ -469,39 +469,37 @@ bool cmdline_applyaction(string s,
string sourcestr, package;
- // Handle task installation. Won't work if tasksel isn't installed.
- if(task_list->find(s)!=task_list->end())
- {
- task t=(*task_list)[s];
-
- printf(_("Note: selecting the task \"%s: %s\" for installation\n"),
- s.c_str(), t.shortdesc.c_str());
-
- for(pkgCache::PkgIterator pkg=(*apt_cache_file)->PkgBegin();
- !pkg.end(); ++pkg)
- {
- std::set<std::string> *tasks = get_tasks(pkg);
-
- for(std::set<std::string>::iterator i = tasks->begin();
- i!=tasks->end(); ++i)
- if(*i==s)
- rval=cmdline_applyaction(action, pkg,
- seen_virtual_packages,
- to_install, to_hold, to_remove, to_purge,
- verbose, source,
- sourcestr,
- policy, arch_only,
- allow_auto,
- term_metrics) && rval;
- }
-
- // break out.
- return rval;
- }
-
if(!cmdline_parse_source(s, source, package, sourcestr))
return false;
+ // Handle task installation. Won't work if tasksel isn't installed.
+ aptitude::apt::task task;
+ string arch;
+ if(cmdline_parse_task(package, task, arch) == true)
+ {
+ printf(_("Note: selecting the task \"%s: %s\" for installation\n"),
+ task.name.c_str(), cw::util::transcode(task.shortdesc).c_str());
+
+ pkgset pkgset;
+ aptitude::apt::get_task_packages(&pkgset, task, arch);
+ for(pkgset::iterator pkg = pkgset.begin();
+ pkg != pkgset.end();
+ ++pkg)
+ {
+ rval = cmdline_applyaction(action, *pkg,
+ seen_virtual_packages,
+ to_install, to_hold, to_remove, to_purge,
+ verbose, source,
+ sourcestr,
+ policy, arch_only,
+ allow_auto,
+ term_metrics) && rval;
+ }
+
+ // break out.
+ return rval;
+ }
+
// This is harmless for other commands, but it won't make sense.
if(source == cmdline_version_version &&
action != cmdline_install &&
diff --git a/src/cmdline/cmdline_changelog.cc b/src/cmdline/cmdline_changelog.cc
index a2ea9e92..17c79fca 100644
--- a/src/cmdline/cmdline_changelog.cc
+++ b/src/cmdline/cmdline_changelog.cc
@@ -143,7 +143,7 @@ void set_name(temp::name n, temp::name *target)
<< std::string(term_metrics->get_screen_width(), ' ')
<< "\r";
- std::cout << _("Err ") << description << std::endl;
+ std::cout << _("Err") << " " << description << std::endl;
}
};
diff --git a/src/cmdline/cmdline_do_action.cc b/src/cmdline/cmdline_do_action.cc
index 739edfa0..8d088379 100644
--- a/src/cmdline/cmdline_do_action.cc
+++ b/src/cmdline/cmdline_do_action.cc
@@ -383,7 +383,7 @@ int cmdline_do_action(int argc, char *argv[],
policy, arch_only, term))
{
printf(_("Abort.\n"));
- return 0;
+ return 1;
}
aptitude::cmdline::apply_user_tags(user_tags);
diff --git a/src/cmdline/cmdline_extract_cache_subset.cc b/src/cmdline/cmdline_extract_cache_subset.cc
index e13bd46b..2a2a3836 100644
--- a/src/cmdline/cmdline_extract_cache_subset.cc
+++ b/src/cmdline/cmdline_extract_cache_subset.cc
@@ -32,6 +32,7 @@
#include <generic/apt/matching/match.h>
#include <generic/apt/matching/parse.h>
#include <generic/apt/matching/pattern.h>
+#include <generic/util/util.h>
// System includes:
@@ -89,8 +90,8 @@ namespace aptitude
pkgCache::PkgIterator pIt = (*apt_cache_file)->FindPkg(arg);
if(pIt.end())
{
- fprintf(stderr, _("No such package \"%s\".\n"),
- arg.c_str());
+ std::cerr << ssprintf(_("No such package \"%s\""), arg.c_str())
+ << std::endl;
ok = false;
}
else
diff --git a/src/cmdline/cmdline_simulate.cc b/src/cmdline/cmdline_simulate.cc
index a50d20c1..e63bd632 100644
--- a/src/cmdline/cmdline_simulate.cc
+++ b/src/cmdline/cmdline_simulate.cc
@@ -58,7 +58,7 @@ int cmdline_simulate(bool as_upgrade,
term_metrics))
{
printf(_("Abort.\n"));
- return 0;
+ return 1;
}
if(verbose==0)
diff --git a/src/cmdline/cmdline_update.cc b/src/cmdline/cmdline_update.cc
index 2bfeaa51..e5035e38 100644
--- a/src/cmdline/cmdline_update.cc
+++ b/src/cmdline/cmdline_update.cc
@@ -41,7 +41,7 @@ using boost::shared_ptr;
void print_autoclean_msg()
{
- printf(_("Deleting obsolete downloaded files\n"));
+ printf("%s\n", _("Deleting obsolete downloaded files"));
}
int cmdline_update(int argc, char *argv[], int verbose)
diff --git a/src/cmdline/cmdline_user_tag.cc b/src/cmdline/cmdline_user_tag.cc
index ba7a5810..e3cd7726 100644
--- a/src/cmdline/cmdline_user_tag.cc
+++ b/src/cmdline/cmdline_user_tag.cc
@@ -34,6 +34,7 @@
#include <generic/apt/matching/match.h>
#include <generic/apt/matching/parse.h>
#include <generic/apt/matching/pattern.h>
+#include <generic/util/util.h>
#include <stdio.h>
#include <string.h>
@@ -127,7 +128,8 @@ namespace aptitude
if(pkg.end())
{
if(quiet == 0)
- fprintf(stderr, _("No such package \"%s\".\n"), argv[i]);
+ std::cerr << ssprintf(_("No such package \"%s\""), argv[i])
+ << std::endl;
all_ok = false;
}
else
diff --git a/src/cmdline/cmdline_util.cc b/src/cmdline/cmdline_util.cc
index 813aceb2..1165e3e4 100644
--- a/src/cmdline/cmdline_util.cc
+++ b/src/cmdline/cmdline_util.cc
@@ -38,7 +38,7 @@
#include <generic/apt/matching/match.h>
#include <generic/apt/matching/parse.h>
#include <generic/apt/matching/pattern.h>
-
+#include <generic/apt/tasks.h>
// System includes:
#include <apt-pkg/error.h>
@@ -252,6 +252,29 @@ bool cmdline_parse_source(const string &input,
return true;
}
+bool cmdline_parse_task(string pattern,
+ aptitude::apt::task &task,
+ string &arch)
+{
+ const string::size_type archfound = pattern.find_last_of(':');
+ arch = "native";
+ if(archfound != string::npos)
+ {
+ arch = pattern.substr(archfound+1);
+ pattern.erase(archfound);
+ }
+
+ if(pattern[pattern.length() - 1] != '^')
+ return false;
+ pattern.erase(pattern.length() - 1);
+
+ const aptitude::apt::task *t = aptitude::apt::find_task(pattern);
+ if(t == NULL)
+ return _error->Error(_("Couldn't find task '%s'"), pattern.c_str());
+
+ task = *t;
+ return true;
+}
namespace
{
diff --git a/src/cmdline/cmdline_util.h b/src/cmdline/cmdline_util.h
index 3a5dea68..9b88c393 100644
--- a/src/cmdline/cmdline_util.h
+++ b/src/cmdline/cmdline_util.h
@@ -29,7 +29,7 @@
#include <generic/apt/download_manager.h>
#include <generic/apt/matching/pattern.h>
#include <generic/apt/matching/match.h> // For structural_match.
-
+#include <generic/apt/tasks.h>
// System includes:
#include <apt-pkg/srcrecords.h>
@@ -94,6 +94,10 @@ bool cmdline_parse_source(const string &input,
string &package,
string &sourcestr);
+bool cmdline_parse_task(std::string pattern,
+ aptitude::apt::task &task,
+ std::string &arch);
+
/** Run the given download and post-download commands using the
* standard command-line UI. Runs the preparation routine, the
* actual download, and the post-download commands.
diff --git a/src/cmdline/cmdline_versions.cc b/src/cmdline/cmdline_versions.cc
index 8f57ff41..57e95d17 100644
--- a/src/cmdline/cmdline_versions.cc
+++ b/src/cmdline/cmdline_versions.cc
@@ -292,7 +292,7 @@ namespace
(*pIt)->get_type() == m::pattern::exact_name)
{
return_value = 1;
- _error->Error(_("No such package \"%s\"."),
+ _error->Error(_("No such package \"%s\""),
(*pIt)->get_exact_name_name().c_str());
}
}
diff --git a/src/generic/apt/apt.cc b/src/generic/apt/apt.cc
index aa010d37..d534b436 100644
--- a/src/generic/apt/apt.cc
+++ b/src/generic/apt/apt.cc
@@ -366,7 +366,7 @@ void apt_close_cache()
else
LOG_TRACE(logger, "No global dependency resolver manager exists; none deleted.");
- reset_tasks();
+ aptitude::apt::reset_tasks();
LOG_TRACE(logger, "Tasks reset.");
@@ -484,7 +484,7 @@ void apt_load_cache(OpProgress *progress_bar, bool do_initselections,
apt_undos->clear_items();
LOG_TRACE(logger, "Loading task information.");
- load_tasks(*progress_bar);
+ aptitude::apt::load_tasks(*progress_bar);
LOG_TRACE(logger, "Loading tags.");
#ifndef HAVE_EPT
load_tags(*progress_bar);
diff --git a/src/generic/apt/download_update_manager.cc b/src/generic/apt/download_update_manager.cc
index b4b7a227..88a55f0d 100644
--- a/src/generic/apt/download_update_manager.cc
+++ b/src/generic/apt/download_update_manager.cc
@@ -127,7 +127,7 @@ void download_update_manager::finish(pkgAcquire::RunResult res,
uri.User.clear();
uri.Password.clear();
const std::string descUri = string(uri);
- _error->Warning(_("Failed to fetch %s: %s\n"), descUri.c_str(), (*it)->ErrorText.c_str());
+ _error->Warning(_("Failed to fetch %s: %s"), descUri.c_str(), (*it)->ErrorText.c_str());
if((*it)->Status == pkgAcquire::Item::StatTransientNetworkError)
{
diff --git a/src/generic/apt/matching/match.cc b/src/generic/apt/matching/match.cc
index 44430ab7..6e3a1763 100644
--- a/src/generic/apt/matching/match.cc
+++ b/src/generic/apt/matching/match.cc
@@ -1672,7 +1672,7 @@ namespace aptitude
{
pkgCache::PkgIterator pkg(target.get_package_iterator(cache));
- std::set<string> *l = get_tasks(pkg);
+ std::set<string> *l = aptitude::apt::get_tasks(pkg);
if(!l)
return NULL;
diff --git a/src/generic/apt/pkg_changelog.cc b/src/generic/apt/pkg_changelog.cc
index 8724d24c..9b1caf33 100644
--- a/src/generic/apt/pkg_changelog.cc
+++ b/src/generic/apt/pkg_changelog.cc
@@ -438,7 +438,7 @@ namespace aptitude
const string source_version(info.get_source_version());
const string section(info.get_section());
const string name(info.get_display_name());
- const string short_description = cw::util::ssprintf(_("ChangeLog of %s"), name.c_str());
+ const string short_description = cw::util::ssprintf(_("Changelog of %s"), name.c_str());
try
{
diff --git a/src/generic/apt/tasks.cc b/src/generic/apt/tasks.cc
index b3930471..6c268b09 100644
--- a/src/generic/apt/tasks.cc
+++ b/src/generic/apt/tasks.cc
@@ -1,6 +1,22 @@
// tasks.cc
//
-// Copyright 2001 Daniel Burrows
+// Copyright (C) 2001 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
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
#include "tasks.h"
#include "apt.h"
@@ -12,19 +28,35 @@
#include <apt-pkg/tagfile.h>
#include <cwidget/generic/util/eassert.h>
-#include <errno.h>
+#include <cwidget/generic/util/transcode.h>
+#include <errno.h>
#include <ctype.h>
#include <map>
#include <vector>
+#include <iterator>
#include <algorithm>
#include <sstream>
+namespace cw = cwidget;
+
using namespace std;
+namespace aptitude {
+namespace apt {
+
+// Stores the various tasks.
map<string, task> *task_list=new map<string, task>;
+task *find_task(const std::string &name)
+{
+ if(task_list->find(name) == task_list->end())
+ return NULL;
+
+ return &((*task_list)[name]);
+}
+
// This is an array indexed by package ID, managed by load_tasks.
// (as usual, it's initialized to NULL)
set<string> *tasks_by_package;
@@ -38,6 +70,86 @@ std::set<std::string> *get_tasks(const pkgCache::PkgIterator &pkg)
return tasks_by_package+pkg->ID;
}
+// Based on task_packages in tasksel.pl.
+bool get_task_packages(std::set<pkgCache::PkgIterator> * const pkgset,
+ const task &task, const string &arch)
+{
+ // key packages are always included
+ for(set<string>::const_iterator it = task.keys.begin();
+ it != task.keys.end();
+ ++it)
+ {
+ pkgCache::PkgIterator pkg = (*apt_cache_file)->FindPkg(*it, arch);
+ if(pkg.end() != false)
+ pkgset->insert(pkg);
+ }
+
+ if(task.packages.empty() == true)
+ {
+ // only key
+ }
+ else if(task.packages[0] == "task-fields")
+ {
+ // task-fields method is built-in for speed
+ for(pkgCache::GrpIterator grp = (*apt_cache_file)->GrpBegin();
+ grp.end() == false;
+ ++grp)
+ {
+ pkgCache::PkgIterator pkg = grp.FindPkg(arch);
+ if(pkg.end() == true)
+ continue;
+ set<string> *tasks = get_tasks(pkg);
+ if(tasks->find(task.name) != tasks->end())
+ pkgset->insert(pkg);
+ }
+ }
+ else if(task.packages[0] == "list")
+ {
+ // list method is build-in for speed
+ for(vector<string>::const_iterator it = task.packages.begin() + 1;
+ it != task.packages.end();
+ ++it)
+ {
+ const pkgCache::PkgIterator pkg = (*apt_cache_file)->FindPkg(*it, arch);
+ if(pkg.end() != false)
+ pkgset->insert(pkg);
+ }
+ }
+ else
+ {
+ // TODO: Handle other methods. One option is to just call
+ // 'tasksel --task-packages' and process the list of search
+ // patterns returned.
+ return _error->Warning(_("Unhandled packages method in task %s: %s"),
+ task.name.c_str(),
+ task.packages[0].c_str());
+ }
+
+ return true;
+}
+
+bool is_task_package(const pkgCache::PkgIterator &pkg)
+{
+ // TODO: Enable this optimization on Debian systems.
+ // if(pkg.Section() != NULL && strcmp(pkg.Section(), "tasks") == 0)
+ // return true;
+ set<string> *pkg_tasks = get_tasks(pkg);
+ for(set<string>::const_iterator it = pkg_tasks->begin();
+ it != pkg_tasks->end();
+ ++it)
+ {
+ if(task_list->find(*it) != task_list->end())
+ {
+ const task t = (*task_list)[*it];
+ if(t.packages.empty() == true
+ && t.keys.find(pkg.Name()) != t.keys.end())
+ return true;
+ }
+ }
+
+ return false;
+}
+
/** \brief Add any tasks found in the given version-file pointer to
* the tasks of the given package.
*/
@@ -48,9 +160,6 @@ static void append_tasks(const pkgCache::PkgIterator &pkg,
// tasks structure.
eassert(tasks_by_package);
- if(strcmp(pkg.Name(), "kdeadmin") == 0)
- eassert(pkg.Name());
-
set<string> &task_set=tasks_by_package[pkg->ID];
if(apt_package_records)
@@ -126,7 +235,6 @@ bool task::keys_present()
{
keys_present_cache=false;
return false;
- break;
}
}
}
@@ -227,6 +335,98 @@ static string rfc822dgettext(string textdomain, string msgid)
return msgstr;
}
+static void set_task_description(task &task, const wstring &desc)
+{
+ const wstring::size_type newline = desc.find(L'\n');
+ task.shortdesc = wstring(desc, 0, newline);
+ task.longdesc = wstring(L"\n ") + wstring(desc, newline+1);
+}
+
+static void read_task_desc(const string &filename, OpProgress &prog)
+{
+ FileFd fd;
+
+ fd.Open(filename, FileFd::ReadOnly);
+ if(!fd.IsOpen())
+ return;
+
+ const unsigned long long file_size = fd.Size();
+ unsigned long long amt = 0;
+ prog.SubProgress(file_size);
+
+ pkgTagFile tagfile(&fd);
+ pkgTagSection section;
+ const string taskdomain("debian-tasks");
+
+ while(tagfile.Step(section))
+ {
+ task newtask;
+ const string taskname(section.FindS("Task"));
+
+ if(!taskname.empty())
+ {
+ newtask.name = taskname;
+ newtask.section = section.FindS("Section");
+ newtask.relevance = section.FindI("Relevance", 5);
+
+ istringstream keyss(section.FindS("Key"));
+ for(istream_iterator<string> key(keyss);
+ key != istream_iterator<string>();
+ ++key)
+ {
+ newtask.keys.insert(*key);
+
+ pkgCache::GrpIterator grp = (*apt_cache_file)->FindGrp(*key);
+ if(grp.end() == true)
+ continue;
+
+ for(pkgCache::PkgIterator pkg = grp.PackageList();
+ pkg.end() == false;
+ pkg = pkg.Group().NextPkg(pkg))
+ tasks_by_package[pkg->ID].insert(taskname);
+ }
+
+ istringstream packagess(section.FindS("Packages"));
+ copy(istream_iterator<string>(packagess),
+ istream_iterator<string>(),
+ back_inserter(newtask.packages));
+
+ string desc = section.FindS("Description");
+ if(desc.empty() == false)
+ {
+ desc = rfc822dgettext(taskdomain, desc);
+ set_task_description(newtask, cw::util::transcode(desc));
+ }
+ else
+ {
+ for(set<string>::const_iterator key = newtask.keys.begin();
+ key != newtask.keys.end();
+ ++key)
+ {
+ const pkgCache::PkgIterator pkg((*apt_cache_file)->FindPkg(*key));
+ if(pkg.end() == true)
+ continue;
+ const pkgCache::VerIterator ver(pkg.VersionList());
+ if(ver.end() == true)
+ continue;
+
+ const wstring desc(get_long_description(ver, apt_package_records));
+ if(desc.empty() == true)
+ continue;
+
+ set_task_description(newtask, desc);
+ break;
+ }
+ }
+
+ (*task_list)[taskname] = newtask;
+ }
+
+ amt += section.size();
+ prog.Progress(amt);
+ }
+}
+
void load_tasks(OpProgress &progress)
{
// Build a list for each package of the tasks that package belongs to.
@@ -262,71 +462,28 @@ void load_tasks(OpProgress &progress)
++i)
append_tasks(i->first.ParentPkg(), i->second);
- FileFd task_file;
-
// Load the task descriptions:
- task_file.Open("/usr/share/tasksel/debian-tasks.desc", FileFd::ReadOnly);
-
- if(!task_file.IsOpen())
+ const char *descdirs[] =
+ {"/usr/share/tasksel/descs",
+ "/usr/local/share/tasksel/descs",
+ NULL};
+ vector<string> descfiles;
+ for(const char **it = descdirs; *it != NULL; ++it)
{
- _error->Discard();
-
- // Allow the task file not to exist (eg, the user might not have
- // tasksel installed)
- if(errno!=ENOENT)
- _error->Errno("load_tasks",
- _("Unable to open /usr/share/tasksel/debian-tasks.desc"));
-
- return;
+ if(DirectoryExists(*it) == false)
+ continue;
+ const vector<string> v =
+ GetListOfFilesInDir(*it, "desc", false, false);
+ copy(v.begin(), v.end(), back_inserter(descfiles));
}
-
- int file_size=task_file.Size();
- int amt=0;
- progress.OverallProgress(0, file_size, 1, _("Reading task descriptions"));
-
- pkgTagFile tagfile(&task_file);
- pkgTagSection section;
- string taskdomain="debian-tasks";
-
- while(tagfile.Step(section))
+ for(vector<string>::const_iterator it = descfiles.begin();
+ it != descfiles.end();
+ ++it)
{
- task newtask;
- string desc;
- string taskname=section.FindS("Task");
-
- if(!taskname.empty())
- {
- istringstream keystr(section.FindS("Key"));
-
- keystr >> ws;
-
- while(!keystr.eof())
- {
- string s;
-
- keystr >> ws >> s >> ws;
-
- newtask.keys.insert(s);
- }
-
- newtask.name=taskname;
- newtask.section=section.FindS("Section");
- newtask.relevance=section.FindI("Relevance", 5);
-
- desc=section.FindS("Description");
-
- string::size_type newline=desc.find('\n');
- newtask.shortdesc=dgettext(taskdomain.c_str(), string(desc, 0, newline).c_str());
- newtask.longdesc=string("\n ");
- newtask.longdesc+=rfc822dgettext(taskdomain, string(desc, newline+1));
-
- (*task_list)[taskname]=newtask;
- }
-
- amt+=section.size();
- progress.OverallProgress(amt, file_size, 1, _("Reading task descriptions"));
+ progress.OverallProgress(it - descfiles.begin(), descfiles.size(), 1,
+ _("Reading task descriptions"));
+ read_task_desc(*it, progress);
}
- progress.OverallProgress(file_size, file_size, 1, _("Reading task descriptions"));
progress.Done();
}
@@ -337,3 +494,6 @@ void reset_tasks()
delete[] tasks_by_package;
tasks_by_package=NULL;
}
+
+}
+}
diff --git a/src/generic/apt/tasks.h b/src/generic/apt/tasks.h
index 7d439db5..d89fa496 100644
--- a/src/generic/apt/tasks.h
+++ b/src/generic/apt/tasks.h
@@ -1,12 +1,31 @@
// tasks.h -*-c++-*-
//
-// Copyright 2001 Daniel Burrows
+// Copyright (C) 2001 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
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+
+#ifndef TASKS_H
+#define TASKS_H
+
+#include <apt-pkg/pkgcache.h>
#include <string>
#include <set>
#include <map>
-#include <apt-pkg/pkgcache.h>
/** \brief Handles parsing the list of tasks and getting the task of a given
* package.
@@ -16,6 +35,9 @@
class OpProgress;
+namespace aptitude {
+namespace apt {
+
class task
{
private:
@@ -31,15 +53,21 @@ public:
std::string name;
std::string section;
- std::string shortdesc;
- std::string longdesc;
+ std::wstring shortdesc;
+ std::wstring longdesc;
std::set<std::string> keys;
+ std::vector<std::string> packages;
bool keys_present();
int relevance;
};
+// Stores the various tasks.
+extern std::map<std::string, task> *task_list;
+
+task *find_task(const std::string &name);
+
/** \brief Get the set of tasks associated with the given package.
*
* The caller should not delete this set; it's managed internally by
@@ -47,8 +75,22 @@ public:
*/
std::set<std::string> *get_tasks(const pkgCache::PkgIterator &pkg);
-// Stores the various tasks.
-extern std::map<std::string, task> *task_list;
+bool get_task_packages(std::set<pkgCache::PkgIterator> * const pkgset,
+ const task &task,
+ const std::string &arch);
+
+/** \brief Returns \b true if the given package is a task package.
+ *
+ * A task package is one that appears in the Key stanza of a task
+ * definition which has no Packages stanza. For example, the package
+ * task-ssh-server in the following definition is a task package:
+ *
+ * Task: ssh-server
+ * Section: server
+ * Key:
+ * task-ssh-server
+ */
+bool is_task_package(const pkgCache::PkgIterator &pkg);
// (re)loads in the current list of available tasks. Necessary after a
// cache reload, for obvious reasons. apt_reload_cache will call this.
@@ -58,3 +100,8 @@ void load_tasks(OpProgress &progress);
// Since the task list contains package iterators, we have to do something
// in case they're still hanging around.
void reset_tasks();
+
+}
+}
+
+#endif
diff --git a/src/main.cc b/src/main.cc
index ea90abed..511715aa 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -1221,7 +1221,7 @@ int main(int argc, char *argv[])
catch(StdinEOFException)
{
printf("%s", _("Abort.\n"));
- return -1;
+ return 1;
}
catch(const cwidget::util::Exception &e)
{
diff --git a/src/pkg_grouppolicy.cc b/src/pkg_grouppolicy.cc
index 66588138..97875c08 100644
--- a/src/pkg_grouppolicy.cc
+++ b/src/pkg_grouppolicy.cc
@@ -1069,14 +1069,25 @@ void pkg_grouppolicy_task::init_section_descriptions()
class task_subtree:public pkg_subtree
{
char relevance[2];
+ void set_relevance(int _relevance)
+ {
+ relevance[0]='z'-_relevance;
+ relevance[1]=0;
+ }
+
public:
task_subtree(const std::wstring &_name, const std::wstring &_description,
desc_signal *_info_signal,
int _relevance)
:pkg_subtree(_name, _description, _info_signal)
{
- relevance[0]='z'-_relevance;
- relevance[1]=0;
+ set_relevance(_relevance);
+ }
+
+ task_subtree(const aptitude::apt::task &_task, desc_signal *_info_signal)
+ : pkg_subtree(_task.shortdesc, _task.longdesc, _info_signal)
+ {
+ set_relevance(_task.relevance);
}
const char *tag() const {return relevance;}
@@ -1085,7 +1096,9 @@ public:
void pkg_grouppolicy_task::add_package(const pkgCache::PkgIterator &pkg,
pkg_subtree *root)
{
- set<string> *tasks=get_tasks(pkg);
+ using aptitude::apt::task_list;
+
+ set<string> *tasks = aptitude::apt::get_tasks(pkg);
eassert(tasks);
@@ -1097,19 +1110,17 @@ void pkg_grouppolicy_task::add_package(const pkgCache::PkgIterator &pkg,
if(found==task_children.end())
{
- string section;
- map<string,task>::iterator taskfound=task_list->find(*i);
+ string section = "unknown";
+ aptitude::apt::task *task = aptitude::apt::find_task(*i);
+ bool taskfound = (task != NULL);
pkg_subtree *newtree, *sectiontree;
- if(taskfound==task_list->end())
- section="unknown";
- else
- {
- if(!taskfound->second.keys_present())
+ if(taskfound == true)
+ {
+ if(task->keys_present() == false)
continue; // skip to the next task of this package.
-
- section=taskfound->second.section;
- }
+ section = task->section;
+ }
if(!tasks_subtree)
{
@@ -1141,11 +1152,8 @@ void pkg_grouppolicy_task::add_package(const pkgCache::PkgIterator &pkg,
else
sectiontree=sectionfound->second;
- if(taskfound!=task_list->end())
- newtree=new task_subtree(cw::util::transcode(taskfound->second.shortdesc),
- cw::util::transcode(taskfound->second.longdesc),
- get_desc_sig(),
- taskfound->second.relevance);
+ if(taskfound == true)
+ newtree=new task_subtree(*task, get_desc_sig());
else
newtree=new task_subtree(cw::util::transcode(*i), L"",
get_desc_sig(), 5);
diff --git a/src/pkg_info_screen.cc b/src/pkg_info_screen.cc
index 32b558f9..52b65bbd 100644
--- a/src/pkg_info_screen.cc
+++ b/src/pkg_info_screen.cc
@@ -135,8 +135,8 @@ void pkg_grouppolicy_info::setup_package_info(const pkgCache::PkgIterator &pkg,
_("Section: "),pkg.Section()?pkg.Section():_("Unknown"),
_("Maintainer: "),rec.Maintainer().c_str(),
_("Architecture: "),pkgCache::VerIterator(ver).Arch(),
- _("Compressed size: "), SizeToStr(ver->Size).c_str(),
- _("Uncompressed size: "), SizeToStr(ver->InstalledSize).c_str(),
+ _("Compressed Size: "), SizeToStr(ver->Size).c_str(),
+ _("Uncompressed Size: "), SizeToStr(ver->InstalledSize).c_str(),
_("Source Package: "),
rec.SourcePkg().empty()?pkg.Name():rec.SourcePkg().c_str())));
diff --git a/src/pkg_item.cc b/src/pkg_item.cc
index 8fe92917..e9d70dfc 100644
--- a/src/pkg_item.cc
+++ b/src/pkg_item.cc
@@ -407,7 +407,7 @@ bool pkg_item::dispatch_key(const cw::config::key &k, cw::tree *owner)
if(system(buf) != 0) { /* FIXME: ignore? */ }
- cerr<<_("Press return to continue.\n");
+ cerr << _("Press Return to continue.") << endl;
getchar();
cw::toplevel::resume();
@@ -424,7 +424,7 @@ bool pkg_item::dispatch_key(const cw::config::key &k, cw::tree *owner)
e->set_package(package, visible_version());
// FIXME: better title
- add_main_widget(e, _("Hierarchy editor"), "", _("Hierarchy Editor"));
+ add_main_widget(e, _("Hierarchy Editor"), "", _("Hierarchy Editor"));
e->connect_key("Quit", &cw::config::global_bindings,
sigc::mem_fun(*e.unsafe_get_ref(), &cw::widget::destroy));
diff --git a/src/solution_fragment.cc b/src/solution_fragment.cc
index 8d8208bb..e0ed1798 100644
--- a/src/solution_fragment.cc
+++ b/src/solution_fragment.cc
@@ -510,7 +510,7 @@ cw::fragment *solution_fragment_with_ids(const aptitude_solution &sol,
if(!unresolved.empty())
{
ids_column.append_newline();
- fragments.push_back(cw::fragf(_("Leave the following dependencies unresolved:%n")));
+ fragments.push_back(cw::fragf("%s%n", _("Leave the following dependencies unresolved:")));
for(std::vector<std::pair<pkgCache::DepIterator, choice> >::const_iterator i = unresolved.begin();
i != unresolved.end(); ++i)
diff --git a/src/ui.cc b/src/ui.cc
index a94ed97d..07fa9f95 100644
--- a/src/ui.cc
+++ b/src/ui.cc
@@ -1214,7 +1214,7 @@ namespace
if(rval != pkgPackageManager::Incomplete)
{
- cerr << _("Press return to continue.\n");
+ cerr << _("Press Return to continue.") << endl;
int c = getchar();
while(c != '\n' && c != EOF)
@@ -1405,6 +1405,9 @@ static void do_show_preview()
static void do_keep_all()
{
+ if(apt_cache_file == NULL)
+ return;
+
auto_ptr<undo_group> undo(new apt_undo_group);
aptitudeDepCache::action_group group(*apt_cache_file, undo.get());
@@ -1415,6 +1418,8 @@ static void do_keep_all()
if(!undo.get()->empty())
apt_undos->add_item(undo.release());
+
+ package_states_changed();
}
static void fixer_dialog_done()
@@ -2306,7 +2311,7 @@ static void do_dump_resolver()
static cw::editline::history_list history;
if(resman != NULL && resman->resolver_exists())
- prompt_string(_("File to which the resolver state should be dumped: "),
+ prompt_string(_("File to write resolver state to: "),
"",
cw::util::arg(sigc::ptr_fun(handle_dump_resolver_response)),
NULL,
diff --git a/src/view_changelog.cc b/src/view_changelog.cc
index 8318a96f..ae7ed465 100644
--- a/src/view_changelog.cc
+++ b/src/view_changelog.cc
@@ -269,7 +269,7 @@ static void do_view_changelog(temp::name n,
string curverstr)
{
string menulabel =
- ssprintf(_("ChangeLog of %s"), pkgname.c_str());
+ ssprintf(_("Changelog of %s"), pkgname.c_str());
string tablabel = ssprintf(_("%s changes"), pkgname.c_str());
string desclabel = _("View the list of changes made to this Debian package.");