Browse Source

Support release selector for volatile files as well

The syntax is a bit awkward, but it is the same as for a package name
and introducing another syntax wouldn't really help usability, so with
apt install ./foo.deb/experimental you will get the dependencies of foo
satisfied by your default release, but if this wouldn't satisfy the
version requirements the candidate for this dependency is switched to
the version from the experimental release. The same applies for apt
build-dep ./foo.dsc/stable-backports which was the initial request.
tags/debian/1.7.0_alpha1
David Kalnischkies 3 years ago
parent
commit
ce9223cc4e
5 changed files with 214 additions and 50 deletions
  1. +73
    -7
      apt-private/private-install.cc
  2. +15
    -2
      apt-private/private-install.h
  3. +31
    -39
      apt-private/private-source.cc
  4. +1
    -2
      apt-private/private-upgrade.cc
  5. +94
    -0
      test/integration/test-apt-install-file-reltag

+ 73
- 7
apt-private/private-install.cc View File

@@ -564,16 +564,16 @@ static const unsigned short MOD_INSTALL = 2;

bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, int UpgradeMode)
{
std::vector<std::string> VolatileCmdL;
std::vector<PseudoPkg> VolatileCmdL;
return DoCacheManipulationFromCommandLine(CmdL, VolatileCmdL, Cache, UpgradeMode);
}
bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<std::string> &VolatileCmdL, CacheFile &Cache, int UpgradeMode)
bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<PseudoPkg> &VolatileCmdL, CacheFile &Cache, int UpgradeMode)
{
std::map<unsigned short, APT::VersionSet> verset;
std::set<std::string> UnknownPackages;
return DoCacheManipulationFromCommandLine(CmdL, VolatileCmdL, Cache, verset, UpgradeMode, UnknownPackages);
}
bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<std::string> &VolatileCmdL, CacheFile &Cache,
bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<PseudoPkg> &VolatileCmdL, CacheFile &Cache,
std::map<unsigned short, APT::VersionSet> &verset, int UpgradeMode, std::set<std::string> &UnknownPackages)
{
// Enter the special broken fixing mode if the user specified arguments
@@ -611,13 +611,18 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<std::stri

for (auto const &I: VolatileCmdL)
{
pkgCache::PkgIterator const P = Cache->FindPkg(I);
pkgCache::PkgIterator const P = Cache->FindPkg(I.name);
if (P.end())
continue;

// Set any version providing the .deb as the candidate.
for (auto Prv = P.ProvidesList(); Prv.end() == false; Prv++)
Cache.GetDepCache()->SetCandidateVersion(Prv.OwnerVer());
{
if (I.release.empty())
Cache.GetDepCache()->SetCandidateVersion(Prv.OwnerVer());
else
Cache.GetDepCache()->SetCandidateRelease(Prv.OwnerVer(), I.release);
}

// via cacheset to have our usual virtual handling
APT::VersionContainerInterface::FromPackage(&(verset[MOD_INSTALL]), Cache, P, APT::CacheSetHelper::CANDIDATE, helper);
@@ -703,6 +708,68 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<std::stri
return true;
}
/*}}}*/
bool AddVolatileSourceFile(pkgSourceList *const SL, PseudoPkg &&pkg, std::vector<PseudoPkg> &VolatileCmdL)/*{{{*/
{
auto const ext = flExtension(pkg.name);
if (ext != "dsc" && FileExists(pkg.name + "/debian/control") == false)
return false;
std::vector<std::string> files;
SL->AddVolatileFile(pkg.name, &files);
for (auto &&f: files)
VolatileCmdL.emplace_back(std::move(f), pkg.arch, pkg.release, pkg.index);
return true;

}
/*}}}*/
bool AddVolatileBinaryFile(pkgSourceList *const SL, PseudoPkg &&pkg, std::vector<PseudoPkg> &VolatileCmdL)/*{{{*/
{
auto const ext = flExtension(pkg.name);
if (ext != "deb" && ext != "ddeb" && ext != "changes")
return false;
std::vector<std::string> files;
SL->AddVolatileFile(pkg.name, &files);
for (auto &&f: files)
VolatileCmdL.emplace_back(std::move(f), pkg.arch, pkg.release, pkg.index);
return true;
}
/*}}}*/
std::vector<PseudoPkg> GetPseudoPackages(pkgSourceList *const SL, CommandLine &CmdL, bool (*Add)(pkgSourceList *const, PseudoPkg &&, std::vector<PseudoPkg> &), std::string const &pseudoArch)/*{{{*/
{
std::vector<PseudoPkg> VolatileCmdL;
std::remove_if(CmdL.FileList + 1, CmdL.FileList + 1 + CmdL.FileSize(), [&](char const *const I) {
if (I != nullptr && (I[0] == '/' || (I[0] == '.' && (I[1] == '\0' || (I[1] == '.' && (I[2] == '\0' || I[2] == '/')) || I[1] == '/'))))
{
PseudoPkg pkg(I, pseudoArch, "", SL->GetVolatileFiles().size());
if (FileExists(I)) // this accepts directories and symlinks, too
{
if (Add(SL, std::move(pkg), VolatileCmdL))
;
else
_error->Error(_("Unsupported file %s given on commandline"), I);
return true;
}
else
{
auto const found = pkg.name.rfind("/");
if (found == pkg.name.find("/"))
_error->Error(_("Unsupported file %s given on commandline"), I);
else
{
pkg.release = pkg.name.substr(found + 1);
pkg.name.erase(found);
if (Add(SL, std::move(pkg), VolatileCmdL))
;
else
_error->Error(_("Unsupported file %s given on commandline"), I);
}
return true;
}
}
return false;
});
return VolatileCmdL;
}
/*}}}*/
// DoInstall - Install packages from the command line /*{{{*/
// ---------------------------------------------------------------------
/* Install named packages */
@@ -721,8 +788,7 @@ struct PkgIsExtraInstalled {
bool DoInstall(CommandLine &CmdL)
{
CacheFile Cache;
std::vector<std::string> VolatileCmdL;
Cache.GetSourceList()->AddVolatileFiles(CmdL, &VolatileCmdL);
auto VolatileCmdL = GetPseudoPackages(Cache.GetSourceList(), CmdL, AddVolatileBinaryFile, "");

// then open the cache
if (Cache.OpenForInstall() == false ||


+ 15
- 2
apt-private/private-install.h View File

@@ -17,9 +17,22 @@ class pkgProblemResolver;

APT_PUBLIC bool DoInstall(CommandLine &Cmd);

bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<std::string> &VolatileCmdL, CacheFile &Cache,
struct PseudoPkg
{
std::string name;
std::string arch;
std::string release;
ssize_t index;
PseudoPkg(std::string const &n, std::string const &a, std::string const &r) : name(n), arch(a), release(r), index(-1) {}
PseudoPkg(std::string const &n, std::string const &a, std::string const &r, ssize_t i) : name(n), arch(a), release(r), index(i) {}
};
std::vector<PseudoPkg> GetPseudoPackages(pkgSourceList *const SL, CommandLine &CmdL, bool (*Add)(pkgSourceList *const, PseudoPkg &&, std::vector<PseudoPkg> &), std::string const &pseudoArch);
bool AddVolatileBinaryFile(pkgSourceList *const SL, PseudoPkg &&pkg, std::vector<PseudoPkg> &VolatileCmdL);
bool AddVolatileSourceFile(pkgSourceList *const SL, PseudoPkg &&pkg, std::vector<PseudoPkg> &VolatileCmdL);

bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<PseudoPkg> &VolatileCmdL, CacheFile &Cache,
std::map<unsigned short, APT::VersionSet> &verset, int UpgradeMode, std::set<std::string> &UnknownPackages);
bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<std::string> &VolatileCmdL, CacheFile &Cache, int UpgradeMode);
bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<PseudoPkg> &VolatileCmdL, CacheFile &Cache, int UpgradeMode);
bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, int UpgradeMode);

APT_PUBLIC bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,


+ 31
- 39
apt-private/private-source.cc View File

@@ -636,15 +636,6 @@ static void WriteBuildDependencyPackage(std::ostringstream &buildDepsPkgFile,
}
bool DoBuildDep(CommandLine &CmdL)
{
CacheFile Cache;
std::vector<std::string> VolatileCmdL;
Cache.GetSourceList()->AddVolatileFiles(CmdL, &VolatileCmdL);

_config->Set("APT::Install-Recommends", false);

if (CmdL.FileSize() <= 1 && VolatileCmdL.empty())
return _error->Error(_("Must specify at least one package to check builddeps for"));

bool StripMultiArch;
std::string hostArch = _config->Find("APT::Get::Host-Architecture");
if (hostArch.empty() == false)
@@ -656,16 +647,18 @@ bool DoBuildDep(CommandLine &CmdL)
}
else
StripMultiArch = true;
auto const nativeArch = _config->Find("APT::Architecture");
std::string const pseudoArch = hostArch.empty() ? nativeArch : hostArch;

CacheFile Cache;
auto VolatileCmdL = GetPseudoPackages(Cache.GetSourceList(), CmdL, AddVolatileSourceFile, pseudoArch);

_config->Set("APT::Install-Recommends", false);

if (CmdL.FileSize() <= 1 && VolatileCmdL.empty())
return _error->Error(_("Must specify at least one package to check builddeps for"));

std::ostringstream buildDepsPkgFile;
struct PseudoPkg
{
std::string name;
std::string arch;
std::string release;
PseudoPkg(std::string const &n, std::string const &a, std::string const &r) :
name(n), arch(a), release(r) {}
};
std::vector<PseudoPkg> pseudoPkgs;
// deal with the build essentials first
{
@@ -681,7 +674,6 @@ bool DoBuildDep(CommandLine &CmdL)
BuildDeps.push_back(rec);
}
std::string const pseudo = "builddeps:essentials";
std::string const nativeArch = _config->Find("APT::Architecture");
WriteBuildDependencyPackage(buildDepsPkgFile, pseudo, nativeArch, BuildDeps);
pseudoPkgs.emplace_back(pseudo, nativeArch, "");
}
@@ -690,34 +682,34 @@ bool DoBuildDep(CommandLine &CmdL)
if (Cache.BuildSourceList() == false)
return false;
pkgSourceList *List = Cache.GetSourceList();
std::string const pseudoArch = hostArch.empty() ? _config->Find("APT::Architecture") : hostArch;

// FIXME: Avoid volatile sources == cmdline assumption
{
auto const VolatileSources = List->GetVolatileFiles();
if (VolatileSources.size() == VolatileCmdL.size())
for (auto &&pkg : VolatileCmdL)
{
for (size_t i = 0; i < VolatileSources.size(); ++i)
if (unlikely(pkg.index == -1))
{
auto const Src = VolatileCmdL[i];
if (DirectoryExists(Src))
ioprintf(c1out, _("Note, using directory '%s' to get the build dependencies\n"), Src.c_str());
else
ioprintf(c1out, _("Note, using file '%s' to get the build dependencies\n"), Src.c_str());
std::unique_ptr<pkgSrcRecords::Parser> Last(VolatileSources[i]->CreateSrcParser());
if (Last == nullptr)
return _error->Error(_("Unable to find a source package for %s"), Src.c_str());

std::string const pseudo = std::string("builddeps:") + Src;
WriteBuildDependencyPackage(buildDepsPkgFile, pseudo, pseudoArch,
GetBuildDeps(Last.get(), Src.c_str(), StripMultiArch, hostArch));
pseudoPkgs.emplace_back(pseudo, pseudoArch, "");
_error->Error(_("Unable to find a source package for %s"), pkg.name.c_str());
continue;
}
if (DirectoryExists(pkg.name))
ioprintf(c1out, _("Note, using directory '%s' to get the build dependencies\n"), pkg.name.c_str());
else
ioprintf(c1out, _("Note, using file '%s' to get the build dependencies\n"), pkg.name.c_str());
std::unique_ptr<pkgSrcRecords::Parser> Last(VolatileSources[pkg.index]->CreateSrcParser());
if (Last == nullptr)
{
_error->Error(_("Unable to find a source package for %s"), pkg.name.c_str());
continue;
}

auto pseudo = std::string("builddeps:") + pkg.name;
WriteBuildDependencyPackage(buildDepsPkgFile, pseudo, pseudoArch,
GetBuildDeps(Last.get(), pkg.name.c_str(), StripMultiArch, hostArch));
pkg.name = std::move(pseudo);
pseudoPkgs.push_back(std::move(pkg));
}
else
return _error->Error("Implementation error: Volatile sources (%lu) and"
"commandline elements (%lu) do not match!", VolatileSources.size(),
VolatileCmdL.size());
VolatileCmdL.clear();
}

bool const WantLock = _config->FindB("APT::Get::Print-URIs", false) == false;


+ 1
- 2
apt-private/private-upgrade.cc View File

@@ -19,8 +19,7 @@
static bool UpgradeHelper(CommandLine &CmdL, int UpgradeFlags)
{
CacheFile Cache;
std::vector<std::string> VolatileCmdL;
Cache.GetSourceList()->AddVolatileFiles(CmdL, &VolatileCmdL);
auto VolatileCmdL = GetPseudoPackages(Cache.GetSourceList(), CmdL, AddVolatileBinaryFile, "");

if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
return false;


+ 94
- 0
test/integration/test-apt-install-file-reltag View File

@@ -0,0 +1,94 @@
#!/bin/sh
set -e

TESTDIR="$(readlink -f "$(dirname "$0")")"
. "$TESTDIR/framework"

setupenvironment
configarchitecture 'i386'

insertpackage 'unstable' 'foo' 'all' '2' 'Depends: foo-common (= 2)'
insertpackage 'unstable' 'foo-common' 'all' '2'
insertpackage 'unstable' 'baz' 'all' '1'
insertpackage 'experimental' 'foo' 'all' '5' 'Depends: foo-common (= 5)'
insertpackage 'experimental' 'foo-common' 'all' '5' 'Source: foo (5)'
insertpackage 'experimental' 'baz' 'all' '2'
setupaptarchive

insertinstalledpackage 'build-essential' 'all' '1'

cat > foobar.dsc <<EOF
Format: 3.0 (native)
Source: foobar
Binary: foobar
Architecture: all
Version: 1
Maintainer: Joe Sixpack <joe@example.org>
Build-Depends: foo (= 5), baz
Standards-Version: 4.1.3
EOF
buildsimplenativepackage 'foobar2' 'all' '1' 'unstable' 'Depends: foo (= 5), baz'

ln -s "$(readlink -f ./incoming/foobar2_1_all.deb)" foobar.deb
mkdir -p foobar
testfailuremsg 'E: Unable to correct problems, you have held broken packages.' apt build-dep "$(readlink -f ./foobar.dsc)" -s
testfailuremsg 'E: Unable to correct problems, you have held broken packages.' apt install "$(readlink -f ./foobar.deb)" -s
testfailuremsg 'E: Unable to correct problems, you have held broken packages.' apt build-dep ./foobar.dsc -s
testfailuremsg 'E: Unable to correct problems, you have held broken packages.' apt install ./foobar.deb -s
cd foobar
testfailuremsg 'E: Unable to correct problems, you have held broken packages.' apt build-dep ../foobar.dsc -s
testfailuremsg 'E: Unable to correct problems, you have held broken packages.' apt install ../foobar.deb -s
cd ..

SUCCESSDSC='The following NEW packages will be installed:
baz foo foo-common
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Inst baz (1 unstable [all])
Inst foo-common (5 experimental [all])
Inst foo (5 experimental [all])
Conf baz (1 unstable [all])
Conf foo-common (5 experimental [all])
Conf foo (5 experimental [all])'
SUCCESSDEB='The following additional packages will be installed:
baz foo foo-common
The following NEW packages will be installed:
baz foo foo-common foobar2
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Inst baz (1 unstable [all])
Inst foo-common (5 experimental [all])
Inst foo (5 experimental [all])
Inst foobar2 (1 local-deb [all])
Conf baz (1 unstable [all])
Conf foo-common (5 experimental [all])
Conf foo (5 experimental [all])
Conf foobar2 (1 local-deb [all])'
testsuccessequal "Note, using file '$(readlink -f ./foobar.dsc)' to get the build dependencies
$SUCCESSDSC" apt build-dep "$(readlink -f ./foobar.dsc)/experimental" -s -q=2
testsuccessequal "Reading package lists...
Building dependency tree...
Note, selecting 'foobar2' instead of '$(readlink -f ./foobar.deb)'
$SUCCESSDEB" apt install "$(readlink -f ./foobar.deb)/experimental" -s
testsuccessequal "Note, using file './foobar.dsc' to get the build dependencies
$SUCCESSDSC" apt build-dep ./foobar.dsc/experimental -sq=2
testsuccessequal "Reading package lists...
Building dependency tree...
Note, selecting 'foobar2' instead of './foobar.deb'
$SUCCESSDEB" apt install "./foobar.deb/experimental" -s
cd foobar
testsuccessequal "Note, using file '../foobar.dsc' to get the build dependencies
$SUCCESSDSC" apt build-dep ../foobar.dsc/experimental -sqq
testsuccessequal "Reading package lists...
Building dependency tree...
Note, selecting 'foobar2' instead of '../foobar.deb'
$SUCCESSDEB" apt install "../foobar.deb/experimental" -s
cd ..

msgmsg 'fail with' 'incorrect release'
testfailuremsg 'E: Unable to correct problems, you have held broken packages.' apt build-dep "$(readlink -f ./foobar.dsc)/stable" -s
testfailuremsg 'E: Unable to correct problems, you have held broken packages.' apt install "$(readlink -f ./foobar.deb)/stable" -s
testfailuremsg 'E: Unable to correct problems, you have held broken packages.' apt build-dep ./foobar.dsc/stable -s
testfailuremsg 'E: Unable to correct problems, you have held broken packages.' apt install ./foobar.deb/stable -s
cd foobar
testfailuremsg 'E: Unable to correct problems, you have held broken packages.' apt build-dep ../foobar.dsc/stable -s
testfailuremsg 'E: Unable to correct problems, you have held broken packages.' apt install ../foobar.deb/stable -s
cd ..

Loading…
Cancel
Save