From 8bd823d0a1f7e08ad94a7110bb118f73348133a1 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 16 Aug 2016 20:08:29 +0200 Subject: [PATCH] add --with-source option and Packages/Sources support We support "./foobar.deb" as a way to install a deb file directly. Recently .changes files were added. This highlights a problem as you can't add the changes file without also trying to install all of them. Now, it could also be handy to add entire Packages/Sources files to perhaps get a bunch of packages in without installing them all implicitly. This commit introduces --with-source which allows to add *.deb, *.changes, *.dsc, source-dirs, Packages & Sources files (the later can also be compressed) without also installing them. --- apt-pkg/deb/debindexfile.cc | 6 +++- apt-pkg/indexfile.cc | 8 ++++- apt-pkg/sourcelist.cc | 34 +++++++++++++++++- apt-private/private-cmndline.cc | 5 +++ doc/apt-cache.8.xml | 15 ++++++++ doc/apt-get.8.xml | 8 ++++- test/integration/test-apt-get-install-deb | 35 +++++++++++++++++++ .../test-apt-key-used-in-maintainerscript | 2 +- 8 files changed, 108 insertions(+), 5 deletions(-) diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index 6a23b2c00..65bd3e6ee 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -80,7 +80,11 @@ debPackagesIndex::debPackagesIndex(IndexTarget const &Target, bool const Trusted std::string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator const &Ver) const { std::string Res = Target.Description; - Res.erase(Target.Description.rfind(' ')); + { + auto const space = Target.Description.rfind(' '); + if (space != std::string::npos) + Res.erase(space); + } Res += " "; Res += Ver.ParentPkg().Name(); diff --git a/apt-pkg/indexfile.cc b/apt-pkg/indexfile.cc index b1435d32c..934943205 100644 --- a/apt-pkg/indexfile.cc +++ b/apt-pkg/indexfile.cc @@ -151,7 +151,13 @@ std::string IndexTarget::Option(OptionKeys const EnumKey) const /*{{{*/ APT_CASE(ALLOW_WEAK); APT_CASE(ALLOW_DOWNGRADE_TO_INSECURE); #undef APT_CASE - case FILENAME: return _config->FindDir("Dir::State::lists") + URItoFileName(URI); + case FILENAME: + { + auto const M = Options.find("FILENAME"); + if (M == Options.end()) + return _config->FindDir("Dir::State::lists") + URItoFileName(URI); + return M->second; + } case EXISTING_FILENAME: std::string const filename = Option(FILENAME); std::vector const types = VectorizeString(Option(COMPRESSIONTYPES), ' '); diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 000539582..f4a84cc9b 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -328,6 +328,9 @@ bool pkgSourceList::ReadMainList() // Only warn if there is no sources.list file. _error->WarningE("RealFileExists", _("Unable to read %s"), Main.c_str()); + for (auto && file: _config->FindVector("APT::Sources::With")) + Res &= AddVolatileFile(file, nullptr); + return Res; } /*}}}*/ @@ -544,6 +547,22 @@ void pkgSourceList::AddVolatileFile(pkgIndexFile * const File) /*{{{*/ VolatileFiles.push_back(File); } /*}}}*/ +static bool fileNameMatches(std::string const &filename, std::string const &idxtype)/*{{{*/ +{ + for (auto && type: APT::Configuration::getCompressionTypes()) + { + if (type == "uncompressed") + { + if (filename == idxtype || APT::String::Endswith(filename, '_' + idxtype)) + return true; + } + else if (filename == idxtype + '.' + type || + APT::String::Endswith(filename, '_' + idxtype + '.' + type)) + return true; + } + return false; +} + /*}}}*/ bool pkgSourceList::AddVolatileFile(std::string const &File, std::vector * const VolatileCmdL)/*{{{*/ { // Note: FileExists matches directories and links, too! @@ -574,7 +593,20 @@ bool pkgSourceList::AddVolatileFile(std::string const &File, std::vectorpush_back(File); diff --git a/apt-private/private-cmndline.cc b/apt-private/private-cmndline.cc index feb8d67a9..a890aafab 100644 --- a/apt-private/private-cmndline.cc +++ b/apt-private/private-cmndline.cc @@ -96,6 +96,7 @@ static bool addArgumentsAPTCache(std::vector &Args, char cons addArg('p', "pkg-cache", "Dir::Cache::pkgcache", CommandLine::HasArg); addArg('s', "src-cache", "Dir::Cache::srcpkgcache", CommandLine::HasArg); + addArg(0, "with-source", "APT::Sources::With::", CommandLine::HasArg); return found_something; } @@ -275,6 +276,7 @@ static bool addArgumentsAPTGet(std::vector &Args, char const addArg(0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean); addArg(0,"install-suggests","APT::Install-Suggests",CommandLine::Boolean); addArg(0,"fix-policy","APT::Get::Fix-Policy-Broken",0); + addArg(0, "with-source", "APT::Sources::With::", CommandLine::HasArg); return found_something; } @@ -307,6 +309,7 @@ static bool addArgumentsAPTMark(std::vector &Args, char const addArg('s',"dry-run","APT::Mark::Simulate",0); addArg('s',"no-act","APT::Mark::Simulate",0); } + addArg(0, "with-source", "APT::Sources::With::", CommandLine::HasArg); return true; } @@ -340,6 +343,8 @@ static bool addArgumentsAPT(std::vector &Args, char const * c else return false; + addArg(0, "with-source", "APT::Sources::With::", CommandLine::HasArg); + return true; } /*}}}*/ diff --git a/doc/apt-cache.8.xml b/doc/apt-cache.8.xml index 4e2de26bc..66f608b13 100644 --- a/doc/apt-cache.8.xml +++ b/doc/apt-cache.8.xml @@ -350,6 +350,21 @@ Reverse Provides: Configuration Item: APT::Cache::Installed. + + + Adds the given file as a source for metadata. Can be repeated to add multiple files. + Supported are currently *.deb, *.dsc, + *.changes, Sources and + Packages files as well as source package directories. + Files are matched based on their name only, not their content! + Sources and Packages can be compressed in any + format apt supports as long as they have the correct extension. If you need to store + multiple of these files in one directory you can prefix a name of your choice with the + last character being an underscore ("_"). Example: my.example_Packages.xz + Note that these sources are treated as trusted (see &apt-secure;). + Configuration Item: APT::Sources::With. + + &apt-commonoptions; diff --git a/doc/apt-get.8.xml b/doc/apt-get.8.xml index 20555b77e..074262595 100644 --- a/doc/apt-get.8.xml +++ b/doc/apt-get.8.xml @@ -577,7 +577,13 @@ README.progress-reporting in the apt doc directory. Configuration Item: Dpkg::Progress and Dpkg::Progress-Fancy. - + + + + Adds the given file as a source for metadata. Can be repeated to add multiple files. + See description in &apt-cache; for further details. + + &apt-commonoptions; diff --git a/test/integration/test-apt-get-install-deb b/test/integration/test-apt-get-install-deb index 3aacc301d..5f2877dfd 100755 --- a/test/integration/test-apt-get-install-deb +++ b/test/integration/test-apt-get-install-deb @@ -64,6 +64,23 @@ Remv foo:i386 [1.0] Inst foo (1.0 local-deb [amd64]) Conf foo (1.0 local-deb [amd64])" aptget install ./incoming/foo_1.0_amd64.deb -s +testsuccessequal 'Reading package lists... +Building dependency tree... +Reading state information... +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget install --with-source ./incoming/foo_1.0_amd64.deb -s + +testsuccessequal 'Reading package lists... +Building dependency tree... +Reading state information... +The following packages will be REMOVED: + foo:i386 +The following NEW packages will be installed: + foo +0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded. +Remv foo:i386 [1.0] +Inst foo (1.0 local-deb [amd64]) +Conf foo (1.0 local-deb [amd64])' aptget install --with-source ./incoming/foo_1.0_amd64.deb foo -s + # Check that installing the local deb works if it is not the candidate echo "Package: foo Pin: version 1.0 @@ -133,3 +150,21 @@ fi sed -i -e '/^Depends: foo/ d' rootdir/var/lib/dpkg/status testsuccess aptget install -y ./incoming/pkg-as-it-should-be_0_all.deb testfailure grep 'is already the newest version' rootdir/tmp/testsuccess.output +testsuccess apt purge -y pkg-as-it-should-be + +echo "Package: pkg-as-it-should-be +Architecture: all +Version: 0 +Installed-Size: 2903 +Filename: incoming/pkg-as-it-should-be_0_all.deb +Size: $(stat -c %s incoming/pkg-as-it-should-be_0_all.deb) +SHA256: $(sha256sum incoming/pkg-as-it-should-be_0_all.deb | cut -d' ' -f 1) +" > Packages +testdpkgnotinstalled 'pkg-as-it-should-be' +testnopackage pkg-as-it-should-be +testsuccess apt install --with-source ./Packages pkg-as-it-should-be -s +testsuccess apt install --with-source ./Packages pkg-as-it-should-be --print-uris +testsuccess apt show --with-source ./Packages pkg-as-it-should-be +testequal 'Package: pkg-as-it-should-be' head -n1 rootdir/tmp/testsuccess.output +testsuccess apt install -y --with-source ./Packages pkg-as-it-should-be +testdpkginstalled 'pkg-as-it-should-be' diff --git a/test/integration/test-apt-key-used-in-maintainerscript b/test/integration/test-apt-key-used-in-maintainerscript index f7008084f..b5ed3279f 100755 --- a/test/integration/test-apt-key-used-in-maintainerscript +++ b/test/integration/test-apt-key-used-in-maintainerscript @@ -32,7 +32,7 @@ testdpkginstalled 'aptkeyuser-depends' testfailure grep '^Warning: This will BREAK' apt.output testsuccess grep '^Warning: apt-key' apt.output -testsuccess apt install ./incoming/aptkeyuser-nodepends_*.changes -y +testsuccess apt install --with-source ./incoming/aptkeyuser-nodepends_*.changes aptkeyuser-nodepends -y cp rootdir/tmp/testsuccess.output apt.output testdpkginstalled 'aptkeyuser-nodepends' testsuccess grep '^Warning: This will BREAK' apt.output -- 2.45.2