From 8abd4ac9a7765d761116b56541df92006a2b322b Mon Sep 17 00:00:00 2001 From: Daniel Hartwig Date: Thu, 28 Jun 2012 12:36:53 +0800 Subject: 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 --- NEWS | 9 +++++++ src/cmdline/cmdline_util.cc | 59 +++++++++++++++++++++++++++++++++++++++++---- src/cmdline/cmdline_util.h | 3 +++ 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); -- cgit v1.2.3