summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vogt <michael.vogt@ubuntu.com>2012-04-25 17:02:24 +0200
committerMichael Vogt <michael.vogt@ubuntu.com>2012-04-25 17:02:24 +0200
commit99b4fefe0f303cf5ae5e8b9116404fc0fcc96e47 (patch)
tree1a3b69e8d10cbf78a7ad278dab0e5b40bf24c69f
parent4d74894b85227f42b65a84f459f011d74946e4f4 (diff)
parentcc04f4ce9eaaf0945775d5233806de7da5d21ff6 (diff)
merged from donkult
-rw-r--r--apt-pkg/acquire-worker.cc39
-rw-r--r--apt-pkg/cdrom.cc21
-rw-r--r--apt-pkg/contrib/configuration.cc149
-rw-r--r--apt-pkg/contrib/configuration.h2
-rw-r--r--apt-pkg/contrib/strutl.cc57
-rw-r--r--apt-pkg/depcache.cc27
-rw-r--r--apt-pkg/edsp/edspsystem.cc2
-rw-r--r--cmdline/apt-config.cc10
-rw-r--r--debian/changelog29
-rw-r--r--doc/apt-config.8.xml16
-rw-r--r--doc/apt-verbatim.ent3
-rwxr-xr-xtest/integration/test-ignore-provides-if-versioned-breaks150
-rwxr-xr-xtest/integration/test-ignore-provides-if-versioned-conflicts150
-rw-r--r--test/libapt/configuration_test.cc18
14 files changed, 550 insertions, 123 deletions
diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc
index 77e2fc311..8bc043c58 100644
--- a/apt-pkg/acquire-worker.cc
+++ b/apt-pkg/acquire-worker.cc
@@ -467,40 +467,19 @@ bool pkgAcquire::Worker::SendConfiguration()
if (OutFd == -1)
return false;
-
- string Message = "601 Configuration\n";
- Message.reserve(2000);
- /* Write out all of the configuration directives by walking the
+ /* Write out all of the configuration directives by walking the
configuration tree */
- const Configuration::Item *Top = _config->Tree(0);
- for (; Top != 0;)
- {
- if (Top->Value.empty() == false)
- {
- string Line = "Config-Item: " + QuoteString(Top->FullTag(),"=\"\n") + "=";
- Line += QuoteString(Top->Value,"\n") + '\n';
- Message += Line;
- }
-
- if (Top->Child != 0)
- {
- Top = Top->Child;
- continue;
- }
-
- while (Top != 0 && Top->Next == 0)
- Top = Top->Parent;
- if (Top != 0)
- Top = Top->Next;
- }
- Message += '\n';
+ std::ostringstream Message;
+ Message << "601 Configuration\n";
+ _config->Dump(Message, NULL, "Config-Item: %F=%V\n", false);
+ Message << '\n';
if (Debug == true)
- clog << " -> " << Access << ':' << QuoteString(Message,"\n") << endl;
- OutQueue += Message;
- OutReady = true;
-
+ clog << " -> " << Access << ':' << QuoteString(Message.str(),"\n") << endl;
+ OutQueue += Message.str();
+ OutReady = true;
+
return true;
}
/*}}}*/
diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc
index 50c204371..c10ca6bd1 100644
--- a/apt-pkg/cdrom.cc
+++ b/apt-pkg/cdrom.cc
@@ -409,27 +409,10 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf)
/* Write out all of the configuration directives by walking the
configuration tree */
- const Configuration::Item *Top = Cnf.Tree(0);
- for (; Top != 0;)
- {
- // Print the config entry
- if (Top->Value.empty() == false)
- Out << Top->FullTag() + " \"" << Top->Value << "\";" << endl;
-
- if (Top->Child != 0)
- {
- Top = Top->Child;
- continue;
- }
-
- while (Top != 0 && Top->Next == 0)
- Top = Top->Parent;
- if (Top != 0)
- Top = Top->Next;
- }
+ _config->Dump(Out, NULL, "%f \"%v\";\n", false);
Out.close();
-
+
if (FileExists(DFile) == true && link(DFile.c_str(),string(DFile + '~').c_str()) != 0)
return _error->Errno("link", "Failed to link %s to %s~", DFile.c_str(), DFile.c_str());
if (rename(NewFile.c_str(),DFile.c_str()) != 0)
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index 36866a35a..4de17e3e1 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -171,48 +171,60 @@ string Configuration::Find(const char *Name,const char *Default) const
string Configuration::FindFile(const char *Name,const char *Default) const
{
const Item *RootItem = Lookup("RootDir");
- std::string rootDir = (RootItem == 0) ? "" : RootItem->Value;
- if(rootDir.size() > 0 && rootDir[rootDir.size() - 1] != '/')
- rootDir.push_back('/');
+ std::string result = (RootItem == 0) ? "" : RootItem->Value;
+ if(result.empty() == false && result[result.size() - 1] != '/')
+ result.push_back('/');
const Item *Itm = Lookup(Name);
if (Itm == 0 || Itm->Value.empty() == true)
{
- if (Default == 0)
- return rootDir;
- else
- return rootDir + Default;
+ if (Default != 0)
+ result.append(Default);
}
-
- string val = Itm->Value;
- while (Itm->Parent != 0)
+ else
{
- if (Itm->Parent->Value.empty() == true)
+ string val = Itm->Value;
+ while (Itm->Parent != 0)
{
- Itm = Itm->Parent;
- continue;
- }
+ if (Itm->Parent->Value.empty() == true)
+ {
+ Itm = Itm->Parent;
+ continue;
+ }
+
+ // Absolute
+ if (val.length() >= 1 && val[0] == '/')
+ {
+ if (val.compare(0, 9, "/dev/null") == 0)
+ val.erase(9);
+ break;
+ }
- // Absolute
- if (val.length() >= 1 && val[0] == '/')
- break;
+ // ~/foo or ./foo
+ if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
+ break;
- // ~/foo or ./foo
- if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
- break;
-
- // ../foo
- if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
- break;
-
- if (Itm->Parent->Value.end()[-1] != '/')
- val.insert(0, "/");
+ // ../foo
+ if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
+ break;
+
+ if (Itm->Parent->Value.end()[-1] != '/')
+ val.insert(0, "/");
- val.insert(0, Itm->Parent->Value);
- Itm = Itm->Parent;
+ val.insert(0, Itm->Parent->Value);
+ Itm = Itm->Parent;
+ }
+ result.append(val);
}
- return rootDir + val;
+ // do some normalisation by removing // and /./ from the path
+ size_t found = string::npos;
+ while ((found = result.find("/./")) != string::npos)
+ result.replace(found, 3, "/");
+ while ((found = result.find("//")) != string::npos)
+ result.replace(found, 2, "/");
+
+ return result;
}
/*}}}*/
// Configuration::FindDir - Find a directory name /*{{{*/
@@ -222,7 +234,12 @@ string Configuration::FindDir(const char *Name,const char *Default) const
{
string Res = FindFile(Name,Default);
if (Res.end()[-1] != '/')
+ {
+ size_t const found = Res.rfind("/dev/null");
+ if (found != string::npos && found == Res.size() - 9)
+ return Res; // /dev/null returning
return Res + '/';
+ }
return Res;
}
/*}}}*/
@@ -482,24 +499,80 @@ bool Configuration::ExistsAny(const char *Name) const
/* Dump the entire configuration space */
void Configuration::Dump(ostream& str)
{
- /* Write out all of the configuration directives by walking the
+ Dump(str, NULL, "%f \"%v\";\n", true);
+}
+void Configuration::Dump(ostream& str, char const * const root,
+ char const * const formatstr, bool const emptyValue)
+{
+ const Configuration::Item* Top = Tree(root);
+ if (Top == 0)
+ return;
+ const Configuration::Item* const Root = (root == NULL) ? NULL : Top;
+ std::vector<std::string> const format = VectorizeString(formatstr, '%');
+
+ /* Write out all of the configuration directives by walking the
configuration tree */
- const Configuration::Item *Top = Tree(0);
- for (; Top != 0;)
- {
- str << Top->FullTag() << " \"" << Top->Value << "\";" << endl;
-
+ do {
+ if (emptyValue == true || Top->Value.empty() == emptyValue)
+ {
+ std::vector<std::string>::const_iterator f = format.begin();
+ str << *f;
+ for (++f; f != format.end(); ++f)
+ {
+ if (f->empty() == true)
+ {
+ ++f;
+ str << '%' << *f;
+ continue;
+ }
+ char const type = (*f)[0];
+ if (type == 'f')
+ str << Top->FullTag();
+ else if (type == 't')
+ str << Top->Tag;
+ else if (type == 'v')
+ str << Top->Value;
+ else if (type == 'F')
+ str << QuoteString(Top->FullTag(), "=\"\n");
+ else if (type == 'T')
+ str << QuoteString(Top->Tag, "=\"\n");
+ else if (type == 'V')
+ str << QuoteString(Top->Value, "=\"\n");
+ else if (type == 'n')
+ str << "\n";
+ else if (type == 'N')
+ str << "\t";
+ else
+ str << '%' << type;
+ str << f->c_str() + 1;
+ }
+ }
+
if (Top->Child != 0)
{
Top = Top->Child;
continue;
}
-
+
while (Top != 0 && Top->Next == 0)
Top = Top->Parent;
if (Top != 0)
Top = Top->Next;
- }
+
+ if (Root != NULL)
+ {
+ const Configuration::Item* I = Top;
+ while(I != 0)
+ {
+ if (I == Root)
+ break;
+ else
+ I = I->Parent;
+ }
+ if (I == 0)
+ break;
+ }
+ } while (Top != 0);
}
/*}}}*/
diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h
index 4c2e75041..ea94c2fe6 100644
--- a/apt-pkg/contrib/configuration.h
+++ b/apt-pkg/contrib/configuration.h
@@ -103,6 +103,8 @@ class Configuration
inline void Dump() { Dump(std::clog); };
void Dump(std::ostream& str);
+ void Dump(std::ostream& str, char const * const root,
+ char const * const format, bool const emptyValue);
Configuration(const Item *Root);
Configuration();
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index 99efa8d98..ca096d736 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/apt-pkg/contrib/strutl.cc
@@ -23,6 +23,7 @@
#include <ctype.h>
#include <string.h>
+#include <sstream>
#include <stdio.h>
#include <algorithm>
#include <unistd.h>
@@ -1168,34 +1169,50 @@ unsigned long RegexChoice(RxChoiceList *Rxs,const char **ListBegin,
return Hits;
}
/*}}}*/
-// ioprintf - C format string outputter to C++ iostreams /*{{{*/
+// {str,io}printf - C format string outputter to C++ strings/iostreams /*{{{*/
// ---------------------------------------------------------------------
/* This is used to make the internationalization strings easier to translate
and to allow reordering of parameters */
-void ioprintf(ostream &out,const char *format,...)
+static bool iovprintf(ostream &out, const char *format,
+ va_list &args, ssize_t &size) {
+ char *S = (char*)malloc(size);
+ ssize_t const n = vsnprintf(S, size, format, args);
+ if (n > -1 && n < size) {
+ out << S;
+ free(S);
+ return true;
+ } else {
+ if (n > -1)
+ size = n + 1;
+ else
+ size *= 2;
+ }
+ free(S);
+ return false;
+}
+void ioprintf(ostream &out,const char *format,...)
{
va_list args;
- va_start(args,format);
-
- // sprintf the description
- char S[4096];
- vsnprintf(S,sizeof(S),format,args);
- out << S;
+ ssize_t size = 400;
+ while (true) {
+ va_start(args,format);
+ if (iovprintf(out, format, args, size) == true)
+ return;
+ va_end(args);
+ }
}
- /*}}}*/
-// strprintf - C format string outputter to C++ strings /*{{{*/
-// ---------------------------------------------------------------------
-/* This is used to make the internationalization strings easier to translate
- and to allow reordering of parameters */
-void strprintf(string &out,const char *format,...)
+void strprintf(string &out,const char *format,...)
{
va_list args;
- va_start(args,format);
-
- // sprintf the description
- char S[4096];
- vsnprintf(S,sizeof(S),format,args);
- out = string(S);
+ ssize_t size = 400;
+ std::ostringstream outstr;
+ while (true) {
+ va_start(args,format);
+ if (iovprintf(outstr, format, args, size) == true)
+ break;
+ va_end(args);
+ }
+ out = outstr.str();
}
/*}}}*/
// safe_snprintf - Safer snprintf /*{{{*/
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index 1eea55560..2656e9b42 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -1152,9 +1152,8 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
}
/* This bit is for processing the possibilty of an install/upgrade
- fixing the problem */
- if (Start->Type != Dep::DpkgBreaks &&
- (DepState[Start->ID] & DepCVer) == DepCVer)
+ fixing the problem for "positive" dependencies */
+ if (Start.IsNegative() == false && (DepState[Start->ID] & DepCVer) == DepCVer)
{
APT::VersionList verlist;
pkgCache::VerIterator Cand = PkgState[Start.TargetPkg()->ID].CandidateVerIter(*this);
@@ -1165,7 +1164,7 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
pkgCache::VerIterator V = Prv.OwnerVer();
pkgCache::VerIterator Cand = PkgState[Prv.OwnerPkg()->ID].CandidateVerIter(*this);
if (Cand.end() == true || V != Cand ||
- VS().CheckDep(Cand.VerStr(), Start->CompareOp, Start.TargetVer()) == false)
+ VS().CheckDep(Prv.ProvideVersion(), Start->CompareOp, Start.TargetVer()) == false)
continue;
verlist.insert(Cand);
}
@@ -1198,13 +1197,13 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
}
continue;
}
-
- /* For conflicts we just de-install the package and mark as auto,
- Conflicts may not have or groups. For dpkg's Breaks we try to
- upgrade the package. */
- if (Start.IsNegative() == true)
+ /* Negative dependencies have no or-group
+ If the dependency isn't versioned, we try if an upgrade might solve the problem.
+ Otherwise we remove the offender if needed */
+ else if (Start.IsNegative() == true && Start->Type != pkgCache::Dep::Obsoletes)
{
SPtrArray<Version *> List = Start.AllTargets();
+ pkgCache::PkgIterator TrgPkg = Start.TargetPkg();
for (Version **I = List; *I != 0; I++)
{
VerIterator Ver(*this,*I);
@@ -1215,15 +1214,17 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
if (PkgState[Pkg->ID].InstallVer == 0)
continue;
- if (PkgState[Pkg->ID].CandidateVer != *I &&
- Start->Type == Dep::DpkgBreaks &&
+ if ((Start->Version != 0 || TrgPkg != Pkg) &&
+ PkgState[Pkg->ID].CandidateVer != PkgState[Pkg->ID].InstallVer &&
+ PkgState[Pkg->ID].CandidateVer != *I &&
MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps) == true)
continue;
- else if (MarkDelete(Pkg,false,Depth + 1, false) == false)
+ else if ((Start->Type == pkgCache::Dep::Conflicts || Start->Type == pkgCache::Dep::DpkgBreaks) &&
+ MarkDelete(Pkg,false,Depth + 1, false) == false)
break;
}
continue;
- }
+ }
}
return Dep.end() == true;
diff --git a/apt-pkg/edsp/edspsystem.cc b/apt-pkg/edsp/edspsystem.cc
index 6b9207451..aae969d9d 100644
--- a/apt-pkg/edsp/edspsystem.cc
+++ b/apt-pkg/edsp/edspsystem.cc
@@ -91,7 +91,7 @@ signed edspSystem::Score(Configuration const &Cnf)
{
if (Cnf.Find("edsp::scenario", "") == "stdin")
return 1000;
- if (FileExists(Cnf.FindFile("edsp::scenario","")) == true)
+ if (RealFileExists(Cnf.FindFile("edsp::scenario","")) == true)
return 1000;
return -1000;
}
diff --git a/cmdline/apt-config.cc b/cmdline/apt-config.cc
index 79ae944df..397ce32df 100644
--- a/cmdline/apt-config.cc
+++ b/cmdline/apt-config.cc
@@ -63,7 +63,13 @@ bool DoShell(CommandLine &CmdL)
/* */
bool DoDump(CommandLine &CmdL)
{
- _config->Dump(cout);
+ bool const empty = _config->FindB("APT::Config::Dump::EmptyValue", true);
+ std::string const format = _config->Find("APT::Config::Dump::Format", "%f \"%v\";\n");
+ if (CmdL.FileSize() == 1)
+ _config->Dump(cout, NULL, format.c_str(), empty);
+ else
+ for (const char **I = CmdL.FileList + 1; *I != 0; ++I)
+ _config->Dump(cout, *I, format.c_str(), empty);
return true;
}
/*}}}*/
@@ -100,6 +106,8 @@ int main(int argc,const char *argv[]) /*{{{*/
{'v',"version","version",0},
{'c',"config-file",0,CommandLine::ConfigFile},
{'o',"option",0,CommandLine::ArbItem},
+ {0,"empty","APT::Config::Dump::EmptyValue",CommandLine::Boolean},
+ {0,"format","APT::Config::Dump::Format",CommandLine::HasArg},
{0,0,0,0}};
CommandLine::Dispatch Cmds[] = {{"shell",&DoShell},
{"dump",&DoDump},
diff --git a/debian/changelog b/debian/changelog
index e0c178a18..34d6991b5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,32 @@
+apt (0.9.3) unstable; urgency=low
+
+ [ David Kalnischkies ]
+ * apt-pkg/contrib/strutl.cc:
+ - remove the message size limit from ioprintf and strprintf
+ * apt-pkg/contrib/configuration.cc:
+ - add a more versatile Dump() method
+ - normalize a bit by replacing // and /./ with / in FindFile
+ - /dev/null is a special absolute path as it has no subdirectories
+ * apt-pkg/acquire-worker.cc:
+ - use Dump() to generate the configuration message for sending
+ * cmdline/apt-config.cc:
+ - make it possible to limit dump to a subtree
+ - implement --empty and --format option for dump
+ * apt-pkg/cdrom.cc:
+ - use Dump() to generate the configuration output
+ * apt-pkg/depcache.cc:
+ - clearly separate 'positive' and 'negative' dependencies and
+ their upgrade-resolution tries in MarkInstall and especially don't
+ treat Conflicts differently compared to Breaks here
+ - provider is only a possible solution if the provides has the right
+ version (or none as we have no versioned provides in debian) and not
+ if the version of the provider matches
+ * edsp/edspsystem.cc:
+ - check with RealFileExists for scenario file as otherwise a directory
+ like one provided with RootDir triggers the usage of EDSP
+
+ -- David Kalnischkies <kalnischkies@gmail.com> Mon, 23 Apr 2012 22:02:58 +0200
+
apt (0.9.2) unstable; urgency=low
[ Michael Vogt ]
diff --git a/doc/apt-config.8.xml b/doc/apt-config.8.xml
index b6fcf4bf2..94aeec059 100644
--- a/doc/apt-config.8.xml
+++ b/doc/apt-config.8.xml
@@ -85,7 +85,21 @@ eval $RES
&apt-cmdblurb;
<variablelist>
-
+ <varlistentry>
+ <term><option>--empty</option></term>
+ <listitem><para>Include options which have an empty value. This is the default, so
+ use --no-empty to remove them from the output.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--format '<replaceable>&percnt;f &#x0022;&percnt;v&#x0022;;&percnt;n</replaceable>'</option></term>
+ <listitem><para>Defines the output of each config option. &percnt;t will be replaced with the tagname,
+ &percnt;f with the complete tagname and &percnt;v with the value of the option.
+ Use uppercase letters and the respective values will be quoted. Additionally
+ &percnt;n will be replaced by a newline, &percnt;N by a tab. A &percnt; can be
+ printed by using &percnt;&percnt;.</para></listitem>
+ </varlistentry>
+
&apt-commonoptions;
</variablelist>
diff --git a/doc/apt-verbatim.ent b/doc/apt-verbatim.ent
index ad4554e2f..3846c17e3 100644
--- a/doc/apt-verbatim.ent
+++ b/doc/apt-verbatim.ent
@@ -269,8 +269,11 @@
&synopsis-help;
</group>
</cmdsynopsis></refsynopsisdiv>">
+<!--<arg><option>- -format '<replaceable>&#37;f \"&#37;v\";&#37;n</replaceable>'</option></arg>-->
<!ENTITY synopsis-command-apt-config "<refsynopsisdiv><cmdsynopsis>
<command>apt-config</command>
+ <arg><option>--empty</option></arg>
+ <arg><option>--format '<replaceable>&percnt;f &#x0022;&percnt;v&#x0022;;&percnt;n</replaceable>'</option></arg>
&synopsis-arg-option;
&synopsis-arg-config;
<group choice='req'>
diff --git a/test/integration/test-ignore-provides-if-versioned-breaks b/test/integration/test-ignore-provides-if-versioned-breaks
new file mode 100755
index 000000000..f8b4544a0
--- /dev/null
+++ b/test/integration/test-ignore-provides-if-versioned-breaks
@@ -0,0 +1,150 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'i386' 'amd64'
+
+insertpackage 'unstable' 'unrlated' 'all' '1.0'
+
+insertinstalledpackage 'foo' 'i386' '2.0'
+insertpackage 'unstable' 'foo' 'i386' '4.0'
+insertpackage 'unstable' 'foo-provider' 'i386' '1.0' 'Provides: foo'
+insertpackage 'unstable' 'foo-breaker-3' 'i386' '1.0' 'Breaks: foo (<< 3.0)'
+insertpackage 'unstable' 'foo-breaker-2' 'i386' '1.0' 'Breaks: foo (<< 2.0)'
+insertpackage 'unstable' 'foo-breaker-none' 'i386' '1.0' 'Breaks: foo'
+
+insertinstalledpackage 'foo-foreign' 'amd64' '2.0' 'Multi-Arch: foreign'
+insertpackage 'unstable' 'foo-foreign' 'amd64' '4.0' 'Multi-Arch: foreign'
+insertpackage 'unstable' 'foo-foreign-provider' 'i386' '1.0' 'Provides: foo-foreign'
+insertpackage 'unstable' 'foo-foreign-breaker-3' 'i386' '1.0' 'Breaks: foo-foreign (<< 3.0)'
+insertpackage 'unstable' 'foo-foreign-breaker-2' 'i386' '1.0' 'Breaks: foo-foreign (<< 2.0)'
+insertpackage 'unstable' 'foo-foreign-breaker-none' 'i386' '1.0' 'Breaks: foo-foreign'
+
+insertinstalledpackage 'foo-same' 'i386,amd64' '2.0' 'Multi-Arch: same'
+insertpackage 'unstable' 'foo-same' 'i386,amd64' '4.0' 'Multi-Arch: same'
+insertpackage 'unstable' 'foo-same-provider' 'i386' '1.0' 'Provides: foo-same'
+insertpackage 'unstable' 'foo-same-breaker-3' 'i386' '1.0' 'Breaks: foo-same (<< 3.0)'
+insertpackage 'unstable' 'foo-same-breaker-2' 'i386' '1.0' 'Breaks: foo-same (<< 2.0)'
+insertpackage 'unstable' 'foo-same-breaker-none' 'i386' '1.0' 'Breaks: foo-same'
+
+
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo-breaker-none : Breaks: foo
+E: Unable to correct problems, you have held broken packages.' aptget install foo-provider foo-breaker-none -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ foo-breaker-2 foo-provider
+0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
+Inst foo-breaker-2 (1.0 unstable [i386])
+Inst foo-provider (1.0 unstable [i386])
+Conf foo-breaker-2 (1.0 unstable [i386])
+Conf foo-provider (1.0 unstable [i386])' aptget install foo-provider foo-breaker-2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+ foo
+The following NEW packages will be installed:
+ foo-breaker-3 foo-provider
+The following packages will be upgraded:
+ foo
+1 upgraded, 2 newly installed, 0 to remove and 3 not upgraded.
+Inst foo [2.0] (4.0 unstable [i386])
+Inst foo-breaker-3 (1.0 unstable [i386])
+Inst foo-provider (1.0 unstable [i386])
+Conf foo (4.0 unstable [i386])
+Conf foo-breaker-3 (1.0 unstable [i386])
+Conf foo-provider (1.0 unstable [i386])' aptget install foo-provider foo-breaker-3 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo-foreign-breaker-none : Breaks: foo-foreign
+E: Unable to correct problems, you have held broken packages.' aptget install foo-foreign-provider foo-foreign-breaker-none -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ foo-foreign-breaker-2 foo-foreign-provider
+0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
+Inst foo-foreign-breaker-2 (1.0 unstable [i386])
+Inst foo-foreign-provider (1.0 unstable [i386])
+Conf foo-foreign-breaker-2 (1.0 unstable [i386])
+Conf foo-foreign-provider (1.0 unstable [i386])' aptget install foo-foreign-provider foo-foreign-breaker-2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+ foo-foreign:amd64
+The following NEW packages will be installed:
+ foo-foreign-breaker-3 foo-foreign-provider
+The following packages will be upgraded:
+ foo-foreign:amd64
+1 upgraded, 2 newly installed, 0 to remove and 3 not upgraded.
+Inst foo-foreign:amd64 [2.0] (4.0 unstable [amd64])
+Inst foo-foreign-breaker-3 (1.0 unstable [i386])
+Inst foo-foreign-provider (1.0 unstable [i386])
+Conf foo-foreign:amd64 (4.0 unstable [amd64])
+Conf foo-foreign-breaker-3 (1.0 unstable [i386])
+Conf foo-foreign-provider (1.0 unstable [i386])' aptget install foo-foreign-provider foo-foreign-breaker-3 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo-same-breaker-none : Breaks: foo-same
+E: Unable to correct problems, you have held broken packages.' aptget install foo-same-provider foo-same-breaker-none -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ foo-same-breaker-2 foo-same-provider
+0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
+Inst foo-same-breaker-2 (1.0 unstable [i386])
+Inst foo-same-provider (1.0 unstable [i386])
+Conf foo-same-breaker-2 (1.0 unstable [i386])
+Conf foo-same-provider (1.0 unstable [i386])' aptget install foo-same-provider foo-same-breaker-2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+ foo-same:amd64 foo-same
+The following NEW packages will be installed:
+ foo-same-breaker-3 foo-same-provider
+The following packages will be upgraded:
+ foo-same:amd64 foo-same
+2 upgraded, 2 newly installed, 0 to remove and 2 not upgraded.
+Inst foo-same:amd64 [2.0] (4.0 unstable [amd64]) [foo-same:amd64 on foo-same:i386] [foo-same:i386 on foo-same:amd64] [foo-same:i386 ]
+Inst foo-same [2.0] (4.0 unstable [i386])
+Conf foo-same:amd64 (4.0 unstable [amd64])
+Conf foo-same (4.0 unstable [i386])
+Inst foo-same-breaker-3 (1.0 unstable [i386])
+Inst foo-same-provider (1.0 unstable [i386])
+Conf foo-same-breaker-3 (1.0 unstable [i386])
+Conf foo-same-provider (1.0 unstable [i386])' aptget install foo-same-provider foo-same-breaker-3 -s
diff --git a/test/integration/test-ignore-provides-if-versioned-conflicts b/test/integration/test-ignore-provides-if-versioned-conflicts
new file mode 100755
index 000000000..44eafcff1
--- /dev/null
+++ b/test/integration/test-ignore-provides-if-versioned-conflicts
@@ -0,0 +1,150 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'i386' 'amd64'
+
+insertpackage 'unstable' 'unrlated' 'all' '1.0'
+
+insertinstalledpackage 'foo' 'i386' '2.0'
+insertpackage 'unstable' 'foo' 'i386' '4.0'
+insertpackage 'unstable' 'foo-provider' 'i386' '1.0' 'Provides: foo'
+insertpackage 'unstable' 'foo-breaker-3' 'i386' '1.0' 'Conflicts: foo (<< 3.0)'
+insertpackage 'unstable' 'foo-breaker-2' 'i386' '1.0' 'Conflicts: foo (<< 2.0)'
+insertpackage 'unstable' 'foo-breaker-none' 'i386' '1.0' 'Conflicts: foo'
+
+insertinstalledpackage 'foo-foreign' 'amd64' '2.0' 'Multi-Arch: foreign'
+insertpackage 'unstable' 'foo-foreign' 'amd64' '4.0' 'Multi-Arch: foreign'
+insertpackage 'unstable' 'foo-foreign-provider' 'i386' '1.0' 'Provides: foo-foreign'
+insertpackage 'unstable' 'foo-foreign-breaker-3' 'i386' '1.0' 'Conflicts: foo-foreign (<< 3.0)'
+insertpackage 'unstable' 'foo-foreign-breaker-2' 'i386' '1.0' 'Conflicts: foo-foreign (<< 2.0)'
+insertpackage 'unstable' 'foo-foreign-breaker-none' 'i386' '1.0' 'Conflicts: foo-foreign'
+
+insertinstalledpackage 'foo-same' 'i386,amd64' '2.0' 'Multi-Arch: same'
+insertpackage 'unstable' 'foo-same' 'i386,amd64' '4.0' 'Multi-Arch: same'
+insertpackage 'unstable' 'foo-same-provider' 'i386' '1.0' 'Provides: foo-same'
+insertpackage 'unstable' 'foo-same-breaker-3' 'i386' '1.0' 'Conflicts: foo-same (<< 3.0)'
+insertpackage 'unstable' 'foo-same-breaker-2' 'i386' '1.0' 'Conflicts: foo-same (<< 2.0)'
+insertpackage 'unstable' 'foo-same-breaker-none' 'i386' '1.0' 'Conflicts: foo-same'
+
+
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo-breaker-none : Conflicts: foo
+E: Unable to correct problems, you have held broken packages.' aptget install foo-provider foo-breaker-none -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ foo-breaker-2 foo-provider
+0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
+Inst foo-breaker-2 (1.0 unstable [i386])
+Inst foo-provider (1.0 unstable [i386])
+Conf foo-breaker-2 (1.0 unstable [i386])
+Conf foo-provider (1.0 unstable [i386])' aptget install foo-provider foo-breaker-2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+ foo
+The following NEW packages will be installed:
+ foo-breaker-3 foo-provider
+The following packages will be upgraded:
+ foo
+1 upgraded, 2 newly installed, 0 to remove and 3 not upgraded.
+Inst foo [2.0] (4.0 unstable [i386])
+Inst foo-breaker-3 (1.0 unstable [i386])
+Inst foo-provider (1.0 unstable [i386])
+Conf foo (4.0 unstable [i386])
+Conf foo-breaker-3 (1.0 unstable [i386])
+Conf foo-provider (1.0 unstable [i386])' aptget install foo-provider foo-breaker-3 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo-foreign-breaker-none : Conflicts: foo-foreign
+E: Unable to correct problems, you have held broken packages.' aptget install foo-foreign-provider foo-foreign-breaker-none -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ foo-foreign-breaker-2 foo-foreign-provider
+0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
+Inst foo-foreign-breaker-2 (1.0 unstable [i386])
+Inst foo-foreign-provider (1.0 unstable [i386])
+Conf foo-foreign-breaker-2 (1.0 unstable [i386])
+Conf foo-foreign-provider (1.0 unstable [i386])' aptget install foo-foreign-provider foo-foreign-breaker-2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+ foo-foreign:amd64
+The following NEW packages will be installed:
+ foo-foreign-breaker-3 foo-foreign-provider
+The following packages will be upgraded:
+ foo-foreign:amd64
+1 upgraded, 2 newly installed, 0 to remove and 3 not upgraded.
+Inst foo-foreign:amd64 [2.0] (4.0 unstable [amd64])
+Inst foo-foreign-breaker-3 (1.0 unstable [i386])
+Inst foo-foreign-provider (1.0 unstable [i386])
+Conf foo-foreign:amd64 (4.0 unstable [amd64])
+Conf foo-foreign-breaker-3 (1.0 unstable [i386])
+Conf foo-foreign-provider (1.0 unstable [i386])' aptget install foo-foreign-provider foo-foreign-breaker-3 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo-same-breaker-none : Conflicts: foo-same
+E: Unable to correct problems, you have held broken packages.' aptget install foo-same-provider foo-same-breaker-none -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ foo-same-breaker-2 foo-same-provider
+0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
+Inst foo-same-breaker-2 (1.0 unstable [i386])
+Inst foo-same-provider (1.0 unstable [i386])
+Conf foo-same-breaker-2 (1.0 unstable [i386])
+Conf foo-same-provider (1.0 unstable [i386])' aptget install foo-same-provider foo-same-breaker-2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+ foo-same:amd64 foo-same
+The following NEW packages will be installed:
+ foo-same-breaker-3 foo-same-provider
+The following packages will be upgraded:
+ foo-same:amd64 foo-same
+2 upgraded, 2 newly installed, 0 to remove and 2 not upgraded.
+Inst foo-same:amd64 [2.0] (4.0 unstable [amd64]) [foo-same:amd64 on foo-same:i386] [foo-same:i386 on foo-same:amd64] [foo-same:i386 ]
+Inst foo-same [2.0] (4.0 unstable [i386])
+Conf foo-same:amd64 (4.0 unstable [amd64])
+Conf foo-same (4.0 unstable [i386])
+Inst foo-same-breaker-3 (1.0 unstable [i386])
+Inst foo-same-provider (1.0 unstable [i386])
+Conf foo-same-breaker-3 (1.0 unstable [i386])
+Conf foo-same-provider (1.0 unstable [i386])' aptget install foo-same-provider foo-same-breaker-3 -s
diff --git a/test/libapt/configuration_test.cc b/test/libapt/configuration_test.cc
index 9a3e2c118..87d5699ef 100644
--- a/test/libapt/configuration_test.cc
+++ b/test/libapt/configuration_test.cc
@@ -80,6 +80,24 @@ int main(int argc,const char *argv[]) {
equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
+ Cnf.Set("RootDir", "/");
+ equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
+ equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
+ Cnf.Set("RootDir", "//./////.////");
+ equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
+ equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
+ Cnf.Set("RootDir", "/rootdir");
+ equals(Cnf.FindFile("Dir::State"), "/rootdir/srv/sid/var/lib/apt");
+ equals(Cnf.FindFile("Dir::Aptitude::State"), "/rootdir/srv/sid/var/lib/aptitude");
+ Cnf.Set("RootDir", "/rootdir/");
+ equals(Cnf.FindFile("Dir::State"), "/rootdir/srv/sid/var/lib/apt");
+ equals(Cnf.FindFile("Dir::Aptitude::State"), "/rootdir/srv/sid/var/lib/aptitude");
+
+ Cnf.Set("Dir::State", "/dev/null");
+ Cnf.Set("Dir::State::lists", "lists/");
+ equals(Cnf.FindDir("Dir::State"), "/rootdir/dev/null");
+ equals(Cnf.FindDir("Dir::State::lists"), "/rootdir/dev/null");
+
//FIXME: Test for configuration file parsing;
// currently only integration/ tests test them implicitly