From adf379e7ad1900db6d3942ac7dca5cec4737d9a1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 11 Dec 2013 08:21:04 +0100 Subject: [PATCH] add support for "apt-get source pkg:arch" --- cmdline/apt-get.cc | 60 +++++++++++++++++++---- test/integration/test-apt-get-source-arch | 60 +++++++++++++++++++++++ 2 files changed, 110 insertions(+), 10 deletions(-) create mode 100755 test/integration/test-apt-get-source-arch diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 581466326..9cc5b4031 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -198,18 +198,31 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgSrcRecords &SrcRecs,string &Src, CacheFile &CacheFile) { - string VerTag, UserRequestedVerTag; + string VerTag, UserRequestedVerTag; + string ArchTag = ""; string RelTag = _config->Find("APT::Default-Release"); string TmpSrc = Name; pkgDepCache *Cache = CacheFile.GetDepCache(); - // extract the version/release from the pkgname - const size_t found = TmpSrc.find_last_of("/="); - if (found != string::npos) { - if (TmpSrc[found] == '/') - RelTag = TmpSrc.substr(found+1); - else - VerTag = UserRequestedVerTag = TmpSrc.substr(found+1); + // extract release + size_t found = TmpSrc.find_last_of("/"); + if (found != string::npos) + { + RelTag = TmpSrc.substr(found+1); + TmpSrc = TmpSrc.substr(0,found); + } + // extract the version + found = TmpSrc.find_last_of("="); + if (found != string::npos) + { + VerTag = UserRequestedVerTag = TmpSrc.substr(found+1); + TmpSrc = TmpSrc.substr(0,found); + } + // extract arch + found = TmpSrc.find_last_of(":"); + if (found != string::npos) + { + ArchTag = TmpSrc.substr(found+1); TmpSrc = TmpSrc.substr(0,found); } @@ -217,10 +230,25 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, install a version and determine the source package name, then look in the archive for a source package of the same name. */ bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source"); - const pkgCache::PkgIterator Pkg = Cache->FindPkg(TmpSrc); + pkgCache::PkgIterator Pkg; + if (ArchTag != "") + Pkg = Cache->FindPkg(TmpSrc, ArchTag); + else + Pkg = Cache->FindPkg(TmpSrc); + + // if we can't find a package but the user qualified with a arch, + // error out here + if (Pkg.end() && ArchTag != "") + { + Src = Name; + _error->Error(_("Can not find a package for architecture '%s'"), + ArchTag.c_str()); + return 0; + } + if (MatchSrcOnly == false && Pkg.end() == false) { - if(VerTag.empty() == false || RelTag.empty() == false) + if(VerTag != "" || RelTag != "" || ArchTag != "") { bool fuzzy = false; // we have a default release, try to locate the pkg. we do it like @@ -240,6 +268,17 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, if (Ver.end() == true) break; } + + // pick highest version for the arch unless the user wants + // something else + if (ArchTag != "" && VerTag == "" && RelTag == "") + { + if(Ver.Arch() != ArchTag) + continue; + if(Cache->VS().CmpVersion(VerTag, Ver.VerStr()) < 0) + VerTag = Ver.VerStr(); + } + // We match against a concrete version (or a part of this version) if (VerTag.empty() == false && (fuzzy == true || Cache->VS().CmpVersion(VerTag, Ver.VerStr()) != 0) && // exact match @@ -280,6 +319,7 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, break; } } + if (Src.empty() == true) { // if we don't have found a fitting package yet so we will diff --git a/test/integration/test-apt-get-source-arch b/test/integration/test-apt-get-source-arch new file mode 100755 index 000000000..3ac6907a9 --- /dev/null +++ b/test/integration/test-apt-get-source-arch @@ -0,0 +1,60 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +configarchitecture "i386" "amd64" + + +# different version for the individual arches +insertpackage 'stable' 'foo' 'amd64' '1.0' +insertsource 'stable' 'foo' 'amd64' '1.0' + +insertpackage 'stable' 'foo' 'i386' '1.0' +insertsource 'stable' 'foo' 'i386' '1.0' +insertpackage 'stable' 'foo' 'i386' '2.0' +insertsource 'stable' 'foo' 'i386' '2.0' + +insertpackage 'oldstable' 'foo' 'i386' '0.1' +insertsource 'oldstable' 'foo' 'i386' '0.1' +# just needed so that there is a release file entry for the test +insertpackage 'oldstable' 'unreleated' 'amd64' '0.1' + +setupaptarchive + +APTARCHIVE=$(readlink -f ./aptarchive) + +HEADER="Reading package lists... +Building dependency tree..." + +# pick :amd64 +testequal "$HEADER +Need to get 0 B of source archives. +'file://${APTARCHIVE}/foo_1.0.dsc' foo_1.0.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e +'file://${APTARCHIVE}/foo_1.0.tar.gz' foo_1.0.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo:amd64 + +# pick :i386 +testequal "$HEADER +Need to get 0 B of source archives. +'file://${APTARCHIVE}/foo_2.0.dsc' foo_2.0.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e +'file://${APTARCHIVE}/foo_2.0.tar.gz' foo_2.0.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo:i386 + +# pick :i386 by release +testequal "$HEADER +Selected version '0.1' (oldstable) for foo +Need to get 0 B of source archives. +'file://${APTARCHIVE}/foo_0.1.dsc' foo_0.1.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e +'file://${APTARCHIVE}/foo_0.1.tar.gz' foo_0.1.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo:i386/oldstable + +# pick :i386 by version +testequal "$HEADER +Need to get 0 B of source archives. +'file://${APTARCHIVE}/foo_1.0.dsc' foo_1.0.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e +'file://${APTARCHIVE}/foo_1.0.tar.gz' foo_1.0.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo:i386=1.0 + +# error on unknown arch +testequal "$HEADER +E: Can not find a package for architecture 'not-a-available-arch' +E: Unable to find a source package for foo:not-a-available-arch" aptget source -q --print-uris foo:not-a-available-arch -- 2.45.2