summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hartwig <mandyke@gmail.com>2012-06-28 12:36:53 +0800
committerDaniel Hartwig <mandyke@gmail.com>2012-06-28 12:36:53 +0800
commit8abd4ac9a7765d761116b56541df92006a2b322b (patch)
treed6678788573b0df94edd562a9c78655a5f598196
parent590590d0eef2fe6903574a956f83f0fd3d0a31f1 (diff)
downloadaptitude-8abd4ac9a7765d761116b56541df92006a2b322b.tar.gz
Improve multi-arch handling of package arguments
* [cmdline]: Package arguments without an arch-qualifier will also consider foreign-arch packages, in order of preference. (LP: #892074) * [cmdline]: Package arguments can use '*' wildcard in their arch-qualifier to select all matching packages, where 'any' would select only the first such package. LP: #892074
-rw-r--r--NEWS9
-rw-r--r--src/cmdline/cmdline_util.cc59
-rw-r--r--src/cmdline/cmdline_util.h3
3 files changed, 66 insertions, 5 deletions
diff --git a/NEWS b/NEWS
index 6d65be82..6d714ad2 100644
--- a/NEWS
+++ b/NEWS
@@ -142,6 +142,15 @@ behaviour is desirable for two reasons:
* [cmdline]: why exits with status 1 if it found no
reasons given the particular arguments
+ * [cmdline]: Package arguments without an arch-qualifier
+ will also consider foreign-arch packages, in
+ order of preference. (LP: #892074)
+
+ * [cmdline]: Package arguments can use '*' wildcard in their
+ arch-qualifier to select all matching packages,
+ where 'any' would select only the first such
+ package.
+
- Internal changes:
* Unified the way packages are selected from command line
diff --git a/src/cmdline/cmdline_util.cc b/src/cmdline/cmdline_util.cc
index 9fc39b55..6fb02999 100644
--- a/src/cmdline/cmdline_util.cc
+++ b/src/cmdline/cmdline_util.cc
@@ -865,6 +865,57 @@ namespace aptitude
return pkg;
}
+ bool pkgset_from_group(pkgset * const pkgset, string name,
+ GlobalError::MsgType error_type)
+ {
+ const string::size_type archfound = name.find_last_of(':');
+ string arch;
+ if(archfound != string::npos)
+ {
+ arch = name.substr(archfound + 1);
+ name.erase(archfound);
+ }
+
+ pkgCache::GrpIterator grp = (*apt_cache_file)->FindGrp(name);
+ if(grp.end() == false)
+ {
+ if(arch.empty() == true)
+ {
+ pkgCache::PkgIterator pkg = grp.FindPreferredPkg();
+ if(pkg.end() == false)
+ {
+ pkgset->insert(pkg);
+ return true;
+ }
+ }
+ else
+ {
+ bool found = false;
+ // for 'linux-any' return the first package matching,
+ // for 'linux-*' return all matches
+ const bool is_global = arch.find('*') != string::npos;
+ APT::CacheFilter::PackageArchitectureMatchesSpecification pams(arch);
+ for(pkgCache::PkgIterator pkg = grp.PackageList();
+ pkg.end() == false;
+ pkg = grp.NextPkg(pkg))
+ {
+ if(pams(pkg) == false)
+ continue;
+ pkgset->insert(pkg);
+ found = true;
+ if(is_global == false)
+ break;
+ }
+ if(found == true)
+ return true;
+ }
+ }
+
+ _error->Insert(error_type,
+ _("Unable to locate package %s"), name.c_str());
+ return false;
+ }
+
bool pkgset_from_task(pkgset * const pkgset, string pattern,
GlobalError::MsgType error_type)
{
@@ -980,11 +1031,9 @@ namespace aptitude
if(aptitude::matching::is_pattern(str) == false)
{
- pkgCache::PkgIterator pkg = pkg_from_name(str, error_type);
- if(pkg.end() == false)
- pkgset->insert(pkg);
- else if(pkgset_from_task(pkgset, str, error_type) == false &&
- pkgset_from_regex(pkgset, str, error_type) == false)
+ if(pkgset_from_group(pkgset, str, error_type) == false
+ && pkgset_from_task(pkgset, str, error_type) == false
+ && pkgset_from_regex(pkgset, str, error_type) == false)
found = false;
}
else if(pkgset_from_pattern(pkgset, str, pattern_error_type) == false)
diff --git a/src/cmdline/cmdline_util.h b/src/cmdline/cmdline_util.h
index 77b18140..26fad8ac 100644
--- a/src/cmdline/cmdline_util.h
+++ b/src/cmdline/cmdline_util.h
@@ -441,6 +441,9 @@ namespace aptitude
}
};
+ bool pkgset_from_group(pkgset * const pkgset, string name,
+ GlobalError::MsgType error_type = GlobalError::ERROR);
+
bool pkgset_from_task(pkgset * const pkgset, string pattern,
GlobalError::MsgType error_type = GlobalError::ERROR);