summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hartwig <mandyke@gmail.com>2012-06-08 17:11:48 +0800
committerDaniel Hartwig <mandyke@gmail.com>2012-06-08 17:11:48 +0800
commit24e4c8dab029ac59437f9392a8d3732c6893a3e3 (patch)
tree65da6aa7aef3c16ac40b3c5a4536a025172d8272
parent85d6f30683f6ede36e7a6a0e78e6e7efa079e056 (diff)
downloadaptitude-24e4c8dab029ac59437f9392a8d3732c6893a3e3.tar.gz
Add pkgset helpers
Ported some code from apt cacheset.cc to populate a pkgset. The function pkgset_from_string will fill a given pkgset with either the exactly named package, or the packages matched by a string predicated by is_pattern. In the future, we should look to directly use the apt cacheset infrastructure. This is currently blocked by our custom implementation of pkgCacheFile (see aptcache.h). Errors that occur in looking up the package (such as no package with that name, or an invalid search pattern) are pushed to the global error list with a customizable error_type (default: ERROR).
-rw-r--r--NEWS5
-rw-r--r--src/cmdline/cmdline_action.cc188
-rw-r--r--src/cmdline/cmdline_download.cc48
-rw-r--r--src/cmdline/cmdline_extract_cache_subset.cc56
-rw-r--r--src/cmdline/cmdline_show.cc86
-rw-r--r--src/cmdline/cmdline_user_tag.cc51
-rw-r--r--src/cmdline/cmdline_util.cc66
-rw-r--r--src/cmdline/cmdline_util.h20
-rw-r--r--src/cmdline/cmdline_why.cc16
9 files changed, 224 insertions, 312 deletions
diff --git a/NEWS b/NEWS
index 85bf1ef0..2bb1bc62 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,11 @@
[6/8/2012]
Version 0.6.9 "All in a days work"
+- Internal changes:
+
+ * Unified the way packages are selected from command line
+ arguments.
+
[5/11/2012]
Version 0.6.8 "Never need a reason,
never need a rhyme"
diff --git a/src/cmdline/cmdline_action.cc b/src/cmdline/cmdline_action.cc
index 574a0efe..8fa2eb62 100644
--- a/src/cmdline/cmdline_action.cc
+++ b/src/cmdline/cmdline_action.cc
@@ -520,114 +520,94 @@ bool cmdline_applyaction(string s,
return false;
}
- if(!aptitude::matching::is_pattern(package))
+ pkgset pkgset;
+ if(aptitude::cmdline::pkgset_from_string(&pkgset, package) == false)
{
- pkgCache::PkgIterator pkg=(*apt_cache_file)->FindPkg(package.c_str());
- if(pkg.end())
- {
- // Assume the user asked for a source package.
- if(action == cmdline_build_depends)
- return cmdline_do_build_depends(package,
- seen_virtual_packages,
- source,
- sourcestr,
- arch_only,
- policy,
- to_install, to_hold,
- to_remove, to_purge,
- verbose,
- allow_auto,
- term_metrics);
-
- // Maybe they misspelled the package name?
- pkgvector possible;
-
- for(pkgCache::PkgIterator j=(*apt_cache_file)->PkgBegin();
- !j.end(); ++j)
- {
- if(!(j.VersionList().end() && j.ProvidesList().end()) &&
- strstr(j.Name(), package.c_str()) != NULL)
- possible.push_back(j);
- }
-
- if(!possible.empty())
- {
- // Don't overwhelm the user.
- if(possible.size()>40)
- printf(_("Couldn't find package \"%s\", and more than 40\npackages contain \"%s\" in their name.\n"), package.c_str(), package.c_str());
- else
- {
- printf(_("Couldn't find package \"%s\". However, the following\npackages contain \"%s\" in their name:\n"), package.c_str(), package.c_str());
- cmdline_show_pkglist(possible, term_metrics);
- }
- }
- else
- {
- for(pkgCache::PkgIterator j=(*apt_cache_file)->PkgBegin();
- !j.end(); ++j)
- {
- for(pkgCache::VerIterator v = j.VersionList();
- !v.end(); ++v)
- {
- std::wstring desc = get_long_description(v, apt_package_records);
- if(desc.find(cw::util::transcode(package)) != desc.npos)
- {
- possible.push_back(j);
- break;
- }
- }
- }
-
- if(possible.empty())
- printf(_("Couldn't find any package whose name or description matched \"%s\"\n"), package.c_str());
- else if(possible.size()>40)
- printf(_("Couldn't find any package matching \"%s\", and more than 40\npackages contain \"%s\" in their description.\n"), package.c_str(), package.c_str());
- else
- {
- printf(_("Couldn't find any package matching \"%s\". However, the following\npackages contain \"%s\" in their description:\n"), package.c_str(), package.c_str());
- cmdline_show_pkglist(possible, term_metrics);
- }
- }
-
- return false;
- }
+ // Assume the user asked for a source package.
+ if(action == cmdline_build_depends)
+ return cmdline_do_build_depends(package,
+ seen_virtual_packages,
+ source,
+ sourcestr,
+ arch_only,
+ policy,
+ to_install, to_hold,
+ to_remove, to_purge,
+ verbose,
+ allow_auto,
+ term_metrics);
+
+ // Maybe they misspelled the package name?
+ pkgvector possible;
+
+ for(pkgCache::PkgIterator j=(*apt_cache_file)->PkgBegin();
+ !j.end(); ++j)
+ {
+ if(!(j.VersionList().end() && j.ProvidesList().end()) &&
+ strstr(j.Name(), package.c_str()) != NULL)
+ possible.push_back(j);
+ }
+
+ if(!possible.empty())
+ {
+ // Don't overwhelm the user.
+ if(possible.size()>40)
+ printf(_("Couldn't find package \"%s\", and more than 40\n"
+ "packages contain \"%s\" in their name.\n"),
+ package.c_str(), package.c_str());
+ else
+ {
+ printf(_("Couldn't find package \"%s\". However, the following\n"
+ "packages contain \"%s\" in their name:\n"),
+ package.c_str(), package.c_str());
+ cmdline_show_pkglist(possible, term_metrics);
+ }
+ }
+ else
+ {
+ for(pkgCache::PkgIterator j=(*apt_cache_file)->PkgBegin();
+ !j.end(); ++j)
+ {
+ for(pkgCache::VerIterator v = j.VersionList();
+ !v.end(); ++v)
+ {
+ std::wstring desc = get_long_description(v, apt_package_records);
+ if(desc.find(cw::util::transcode(package)) != desc.npos)
+ {
+ possible.push_back(j);
+ break;
+ }
+ }
+ }
+
+ if(possible.empty())
+ printf(_("Couldn't find any package whose name or description matched \"%s\"\n"),
+ package.c_str());
+ else if(possible.size()>40)
+ printf(_("Couldn't find any package matching \"%s\", and more than 40\n"
+ "packages contain \"%s\" in their description.\n"),
+ package.c_str(), package.c_str());
+ else
+ {
+ printf(_("Couldn't find any package matching \"%s\". However, the following\n"
+ "packages contain \"%s\" in their description:\n"),
+ package.c_str(), package.c_str());
+ cmdline_show_pkglist(possible, term_metrics);
+ }
+ }
- 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);
+ return false;
}
- else
- {
- cw::util::ref_ptr<pattern> p(parse(package.c_str()));
- if(!p.valid())
- {
- _error->DumpErrors();
- return false;
- }
- pkg_results_list matches;
- cw::util::ref_ptr<search_cache> search_info(search_cache::create());
- search(p, search_info, matches,
- *apt_cache_file,
- *apt_package_records);
- for(pkg_results_list::const_iterator it = matches.begin();
- it != matches.end();
- ++it)
- {
- if(!cmdline_applyaction(action, it->first,
- seen_virtual_packages,
- to_install, to_hold, to_remove, to_purge,
- verbose, source,
- sourcestr,
- policy, arch_only,
- allow_auto,
- term_metrics))
- rval = false;
- }
- }
+ for(pkgset::const_iterator it = pkgset.begin();
+ it != pkgset.end();
+ ++it)
+ rval &= cmdline_applyaction(action, *it,
+ seen_virtual_packages,
+ to_install, to_hold, to_remove, to_purge,
+ verbose, source,
+ sourcestr, policy, arch_only, allow_auto,
+ term_metrics);
return rval;
}
diff --git a/src/cmdline/cmdline_download.cc b/src/cmdline/cmdline_download.cc
index 879e4985..e3ccb80c 100644
--- a/src/cmdline/cmdline_download.cc
+++ b/src/cmdline/cmdline_download.cc
@@ -87,49 +87,13 @@ int cmdline_download(int argc, char *argv[])
sourcestr = default_release;
}
- std::vector<pkgCache::PkgIterator> packages;
+ pkgset packages;
+ if(aptitude::cmdline::pkgset_from_string(&packages, name) == false)
+ continue;
- if(!aptitude::matching::is_pattern(name))
- {
- pkgCache::PkgIterator pkg=(*apt_cache_file)->FindPkg(name);
- if(pkg.end())
- {
- _error->Error(_("Can't find a package named \"%s\""), name.c_str());
- continue;
- }
-
- packages.push_back(pkg);
- }
- else
- {
- using namespace aptitude::matching;
- using cwidget::util::ref_ptr;
- ref_ptr<pattern> p(parse(name.c_str()));
- if(!p.valid())
- {
- _error->DumpErrors();
- return false;
- }
-
- pkg_results_list matches;
- ref_ptr<search_cache> search_info(search_cache::create());
- search(p, search_info,
- matches,
- *apt_cache_file,
- *apt_package_records);
-
- for(pkg_results_list::const_iterator it = matches.begin();
- it != matches.end();
- ++it)
- packages.push_back(it->first);
-
- // Maybe there should be a warning here if packages is
- // empty? TODO: think about it again when the string freeze
- // is lifted post-lenny.
- }
-
- for(std::vector<pkgCache::PkgIterator>::const_iterator it =
- packages.begin(); it != packages.end(); ++it)
+ for(pkgset::const_iterator it = packages.begin();
+ it != packages.end();
+ ++it)
{
const pkgCache::PkgIterator pkg = *it;
diff --git a/src/cmdline/cmdline_extract_cache_subset.cc b/src/cmdline/cmdline_extract_cache_subset.cc
index a5cc2086..e4620534 100644
--- a/src/cmdline/cmdline_extract_cache_subset.cc
+++ b/src/cmdline/cmdline_extract_cache_subset.cc
@@ -72,7 +72,7 @@ namespace aptitude
}
bool ok = true;
- std::set<pkgCache::PkgIterator> packages;
+ pkgset packages;
if(argc == 2)
{
for(pkgCache::PkgIterator pIt = (*apt_cache_file)->PkgBegin();
@@ -82,58 +82,14 @@ namespace aptitude
else
{
for(int i = 2; i < argc; ++i)
- {
- std::string arg(argv[i]);
-
- if(!aptitude::matching::is_pattern(arg))
- {
- pkgCache::PkgIterator pIt = (*apt_cache_file)->FindPkg(arg);
- if(pIt.end())
- {
- std::cerr << ssprintf(_("No such package \"%s\""), arg.c_str())
- << std::endl;
- ok = false;
- }
- else
- packages.insert(pIt);
- }
- else
- {
- using namespace aptitude::matching;
- using cwidget::util::ref_ptr;
-
- ref_ptr<pattern> p = parse(arg);
-
- if(p.valid())
- {
- _error->DumpErrors();
- }
- else
- {
- pkg_results_list matches;
- ref_ptr<search_cache> search_info(search_cache::create());
- search(p, search_info,
- matches,
- *apt_cache_file,
- *apt_package_records);
-
- for(pkg_results_list::const_iterator it = matches.begin();
- it != matches.end();
- ++it)
- packages.insert(it->first);
- }
- }
- }
+ ok &= pkgset_from_string(&packages, argv[i]);
}
if(!ok)
- return 2;
-
- if(packages.size() == 0)
- {
- printf(_("No packages were selected by the given search pattern; nothing to do.\n"));
- return 0;
- }
+ {
+ _error->DumpErrors();
+ return 2;
+ }
aptitude::apt::make_truncated_state_copy(out_dir, packages);
diff --git a/src/cmdline/cmdline_show.cc b/src/cmdline/cmdline_show.cc
index 443eaf28..0455aff7 100644
--- a/src/cmdline/cmdline_show.cc
+++ b/src/cmdline/cmdline_show.cc
@@ -570,65 +570,23 @@ bool do_cmdline_show(string s, int verbose, const shared_ptr<terminal_metrics> &
sourcestr = default_release;
}
- bool is_pattern = aptitude::matching::is_pattern(name);
- pkgCache::PkgIterator pkg;
-
- if(!is_pattern)
- {
- pkg=(*apt_cache_file)->FindPkg(name);
-
- if(pkg.end())
- {
- _error->Error(_("Unable to locate package %s"), s.c_str());
- return false;
- }
- }
-
- if(!is_pattern && !pkg.end())
- return do_cmdline_show_target(pkg,
- source,
- sourcestr,
- verbose,
- has_explicit_source,
- term_metrics);
- else if(is_pattern)
- {
- using namespace aptitude::matching;
- using cwidget::util::ref_ptr;
-
- ref_ptr<pattern> p(parse(name));
-
- if(!p.valid())
- {
- _error->Error(_("Unable to parse pattern %s"), name.c_str());
- return false;
- }
+ pkgset pkgset;
+ if(aptitude::cmdline::pkgset_from_string(&pkgset, s, GlobalError::NOTICE) == false)
+ return false;
- pkg_results_list matches;
- ref_ptr<search_cache> search_info(search_cache::create());
- search(p, search_info,
- matches,
- *apt_cache_file,
- *apt_package_records);
+ bool rval = true;
- for(pkg_results_list::const_iterator it = matches.begin();
- it != matches.end();
- ++it)
- {
- if(!do_cmdline_show_target(it->first,
- source,
- sourcestr,
- verbose,
- has_explicit_source,
- term_metrics))
- return false;
- }
- }
- else
- ; // TODO: print an error message -- Christian will kill me if I
- // make the pofile bigger right now.
+ for(pkgset::const_iterator it = pkgset.begin();
+ it != pkgset.end();
+ ++it)
+ rval &= do_cmdline_show_target(*it,
+ source,
+ sourcestr,
+ verbose,
+ has_explicit_source,
+ term_metrics);
- return true;
+ return rval;
}
int cmdline_show(int argc, char *argv[], int verbose)
@@ -647,17 +605,11 @@ int cmdline_show(int argc, char *argv[], int verbose)
}
for(int i=1; i<argc; ++i)
- if(!do_cmdline_show(argv[i], verbose, term))
- {
- _error->DumpErrors();
- return -1;
- }
+ do_cmdline_show(argv[i], verbose, term);
- if(_error->PendingError())
- {
- _error->DumpErrors();
- return -1;
- }
+ int rval = _error->PendingError() == true ? -1 : 0;
+
+ _error->DumpErrors(GlobalError::DEBUG);
- return 0;
+ return rval;
}
diff --git a/src/cmdline/cmdline_user_tag.cc b/src/cmdline/cmdline_user_tag.cc
index 3cc29618..ca61d783 100644
--- a/src/cmdline/cmdline_user_tag.cc
+++ b/src/cmdline/cmdline_user_tag.cc
@@ -122,48 +122,21 @@ namespace aptitude
bool all_ok = true;
for(int i = 2; i < argc; ++i)
{
- if(!aptitude::matching::is_pattern(argv[i]))
- {
- pkgCache::PkgIterator pkg = (*apt_cache_file)->FindPkg(argv[i]);
- if(pkg.end())
- {
- if(quiet == 0)
- std::cerr << ssprintf(_("No such package \"%s\""), argv[i])
- << std::endl;
- all_ok = false;
- }
- else
- do_user_tag(action, tag, pkg, verbose);
- }
- else
- {
- using namespace aptitude::matching;
- using cwidget::util::ref_ptr;
-
- ref_ptr<pattern> p(parse(argv[i]));
-
- if(!p.valid())
- {
- _error->DumpErrors();
- all_ok = false;
- }
- else
- {
- pkg_results_list matches;
- ref_ptr<search_cache> search_info(search_cache::create());
- search(p, search_info,
- matches,
- *apt_cache_file,
- *apt_package_records);
-
- for(pkg_results_list::const_iterator it = matches.begin();
- it != matches.end();
- ++it)
- do_user_tag(action, tag, it->first, verbose);
- }
+ pkgset packages;
+ if(pkgset_from_string(&packages, argv[i]) == false)
+ all_ok = false;
+ else
+ {
+ for(pkgset::const_iterator it = packages.begin();
+ it != packages.end();
+ ++it)
+ do_user_tag(action, tag, *it, verbose);
}
}
+ if(all_ok == false)
+ _error->DumpErrors();
+
shared_ptr<OpProgress> text_progress = make_text_progress(false, term, term, term);
if(!(*apt_cache_file)->save_selection_list(*text_progress))
return 1;
diff --git a/src/cmdline/cmdline_util.cc b/src/cmdline/cmdline_util.cc
index 1165e3e4..22045fcb 100644
--- a/src/cmdline/cmdline_util.cc
+++ b/src/cmdline/cmdline_util.cc
@@ -812,5 +812,71 @@ namespace aptitude
return output;
}
+
+ pkgCache::PkgIterator pkg_from_name(const string &str,
+ GlobalError::MsgType error_type)
+ {
+ pkgCache::PkgIterator pkg = (*apt_cache_file)->FindPkg(str.c_str());
+
+ if(pkg.end() == true)
+ _error->Insert(error_type,
+ _("Unable to locate package %s"), str.c_str());
+ return pkg;
+ }
+
+ bool pkgset_from_pattern(pkgset *packages, const string &pattern,
+ GlobalError::MsgType error_type)
+ {
+ using aptitude::matching::pkg_results_list;
+ using aptitude::matching::search_cache;
+ using cwidget::util::ref_ptr;
+
+ if(aptitude::matching::is_pattern(pattern) == false)
+ return false;
+
+ ref_ptr<aptitude::matching::pattern> p(aptitude::matching::parse(pattern));
+ if(p.valid() == false)
+ return _error->Insert(error_type,
+ _("Unable to parse pattern '%s'"), pattern.c_str());
+
+ pkg_results_list matches;
+ ref_ptr<search_cache> search_info(search_cache::create());
+ search(p, search_info,
+ matches,
+ *apt_cache_file,
+ *apt_package_records);
+
+ if(matches.empty() == true)
+ return _error->Insert(error_type,
+ _("Couldn't find any package for pattern '%s'"),
+ pattern.c_str());
+
+ for(pkg_results_list::const_iterator it = matches.begin();
+ it != matches.end();
+ ++it)
+ {
+ packages->insert(it->first);
+ }
+ return true;
+ }
+
+ bool pkgset_from_string(pkgset *packages, const string &str,
+ GlobalError::MsgType error_type)
+ {
+ bool found = true;
+ _error->PushToStack();
+
+ pkgCache::PkgIterator pkg = pkg_from_name(str, error_type);
+ if(pkg.end() == false)
+ packages->insert(pkg);
+ else if(pkgset_from_pattern(packages, str, error_type) == false)
+ found = false;
+
+ if(found == true)
+ _error->RevertToStack();
+ else
+ _error->MergeWithStack();
+ return found;
+ }
}
}
diff --git a/src/cmdline/cmdline_util.h b/src/cmdline/cmdline_util.h
index 9b88c393..b87daa1d 100644
--- a/src/cmdline/cmdline_util.h
+++ b/src/cmdline/cmdline_util.h
@@ -431,6 +431,26 @@ namespace aptitude
return std::wstring();
}
};
+
+ /** \brief Fill a pkgset using the given matching pattern.
+ *
+ * This does not try any string as a search pattern, only those
+ * which contain explicit search terms or regex characters.
+ */
+ bool pkgset_from_pattern(pkgset *packages, const string &pattern,
+ GlobalError::MsgType error_type = GlobalError::ERROR);
+
+ /** \brief Fill a pkgset using the given string. If the
+ * string names exactly a package then insert that package,
+ * otherwise, if the string is a search pattern, add all matching
+ * packages.
+ *
+ * Based on cacheset.cc(PackageContainerInterface::FromString).
+ * TODO: Should be replaced with cacheset functions once we have
+ * become more compatible with them.
+ */
+ bool pkgset_from_string(pkgset *packages, const string &str,
+ GlobalError::MsgType error_type = GlobalError::ERROR);
}
}
diff --git a/src/cmdline/cmdline_why.cc b/src/cmdline/cmdline_why.cc
index 6781d6b7..2fccc43a 100644
--- a/src/cmdline/cmdline_why.cc
+++ b/src/cmdline/cmdline_why.cc
@@ -1290,18 +1290,14 @@ bool interpret_why_args(const std::vector<std::string> &args,
for(std::vector<std::string>::const_iterator it = args.begin();
it != args.end(); ++it)
{
- // If there isn't a tilde, treat it as an exact package name.
cwidget::util::ref_ptr<pattern> p;
- if(!aptitude::matching::is_pattern(*it))
- {
- pkgCache::PkgIterator pkg = (*apt_cache_file)->FindPkg(*it);
- if(pkg.end())
- _error->Error(_("No package named \"%s\" exists."), it->c_str());
- else
- p = pattern::make_name(ssprintf("^%s$", pkg.Name()));
- }
+ pkgCache::PkgIterator pkg = (*apt_cache_file)->FindPkg(*it);
+ if(pkg.end() == false)
+ p = pattern::make_exact_name(pkg.Name());
+ else if(aptitude::matching::is_pattern(*it) == true)
+ p = parse(*it);
else
- p = parse(*it);
+ _error->Error(_("Unable to locate package %s"), (*it).c_str());
if(!p.valid())
parsing_arguments_failed = true;