summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2015-06-21 16:47:53 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2015-08-10 17:25:26 +0200
commit463c8d801595ce5ac94d7c032264820be7434232 (patch)
tree79963d92b9766709b07d0c5cbc42638896d3450e
parent3d8232bf97ce11818fb07813a71136484ea1a44a (diff)
support lang= and target= sources.list options
We support arch= for a while, now we finally add lang= as well and as a first simple way of controlling which targets to acquire also target=. This asked for a redesign of the internal API of parsing and storing information about 'deb' and 'deb-src' lines. As this API isn't visible to the outside no damage done through. Beside being a nice cleanup (= it actually does more in less lines) it also provides us with a predictable order of architectures as provides in the configuration rather than based on string sorting-order, so that now the native architecture is parsed/displayed first. Observeable e.g. in apt-get output.
-rw-r--r--apt-pkg/deb/debindexfile.cc6
-rw-r--r--apt-pkg/deb/debmetaindex.cc430
-rw-r--r--apt-pkg/deb/debmetaindex.h38
-rw-r--r--apt-pkg/sourcelist.cc40
-rw-r--r--apt-pkg/sourcelist.h8
-rw-r--r--cmdline/apt-get.cc4
-rw-r--r--doc/sources.list.5.xml16
-rwxr-xr-xtest/integration/test-bug-632221-cross-dependency-satisfaction22
-rwxr-xr-xtest/integration/test-ignore-provides-if-versioned-breaks10
-rwxr-xr-xtest/integration/test-ignore-provides-if-versioned-conflicts10
-rwxr-xr-xtest/integration/test-sourceslist-lang-plusminus-options87
11 files changed, 354 insertions, 317 deletions
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index 29a9a941c..c5086b04b 100644
--- a/apt-pkg/deb/debindexfile.cc
+++ b/apt-pkg/deb/debindexfile.cc
@@ -510,7 +510,7 @@ class APT_HIDDEN debIFTypeDebPkgFile : public pkgIndexFile::Type
{
return new debDebFileRecordParser(File.FileName());
};
- debIFTypeDebPkgFile() {Label = "deb Package file";};
+ debIFTypeDebPkgFile() {Label = "Debian deb file";};
};
class APT_HIDDEN debIFTypeDscFile : public pkgIndexFile::Type
{
@@ -519,7 +519,7 @@ class APT_HIDDEN debIFTypeDscFile : public pkgIndexFile::Type
{
return new debDscRecordParser(DscFile, NULL);
};
- debIFTypeDscFile() {Label = "dsc File Source Index";};
+ debIFTypeDscFile() {Label = "Debian dsc file";};
};
class APT_HIDDEN debIFTypeDebianSourceDir : public pkgIndexFile::Type
{
@@ -528,7 +528,7 @@ class APT_HIDDEN debIFTypeDebianSourceDir : public pkgIndexFile::Type
{
return new debDscRecordParser(SourceDir + string("/debian/control"), NULL);
};
- debIFTypeDebianSourceDir() {Label = "debian/control File Source Index";};
+ debIFTypeDebianSourceDir() {Label = "Debian control file";};
};
APT_HIDDEN debIFTypeSrc _apt_Src;
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index 5a517b290..f690a8d64 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -29,11 +29,25 @@
#include <unistd.h>
#include <string.h>
-using namespace std;
-
-string debReleaseIndex::MetaIndexInfo(const char *Type) const
+class APT_HIDDEN debReleaseIndexPrivate /*{{{*/
+{
+ public:
+ struct APT_HIDDEN debSectionEntry
+ {
+ std::string Name;
+ std::vector<std::string> Targets;
+ std::vector<std::string> Architectures;
+ std::vector<std::string> Languages;
+ };
+
+ std::vector<debSectionEntry> DebEntries;
+ std::vector<debSectionEntry> DebSrcEntries;
+};
+ /*}}}*/
+// ReleaseIndex::MetaIndex* - display helpers /*{{{*/
+std::string debReleaseIndex::MetaIndexInfo(const char *Type) const
{
- string Info = ::URI::ArchiveOnly(URI) + ' ';
+ std::string Info = ::URI::ArchiveOnly(URI) + ' ';
if (Dist[Dist.size() - 1] == '/')
{
if (Dist != "/")
@@ -50,15 +64,15 @@ std::string debReleaseIndex::Describe() const
return MetaIndexInfo("Release");
}
-string debReleaseIndex::MetaIndexFile(const char *Type) const
+std::string debReleaseIndex::MetaIndexFile(const char *Type) const
{
return _config->FindDir("Dir::State::lists") +
URItoFileName(MetaIndexURI(Type));
}
-string debReleaseIndex::MetaIndexURI(const char *Type) const
+std::string debReleaseIndex::MetaIndexURI(const char *Type) const
{
- string Res;
+ std::string Res;
if (Dist == "/")
Res = URI;
@@ -70,8 +84,8 @@ string debReleaseIndex::MetaIndexURI(const char *Type) const
Res += Type;
return Res;
}
-
-std::string debReleaseIndex::LocalFileName() const
+ /*}}}*/
+std::string debReleaseIndex::LocalFileName() const /*{{{*/
{
// see if we have a InRelease file
std::string PathInRelease = MetaIndexFile("InRelease");
@@ -84,28 +98,24 @@ std::string debReleaseIndex::LocalFileName() const
return "";
}
-
-debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) :
- metaIndex(URI, Dist, "deb"), d(NULL), Trusted(CHECK_TRUST)
+ /*}}}*/
+// ReleaseIndex Con- and Destructors /*{{{*/
+debReleaseIndex::debReleaseIndex(std::string const &URI, std::string const &Dist) :
+ metaIndex(URI, Dist, "deb"), d(new debReleaseIndexPrivate()), Trusted(CHECK_TRUST)
{}
-
-debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist, bool const Trusted) :
- metaIndex(URI, Dist, "deb"), d(NULL) {
+debReleaseIndex::debReleaseIndex(std::string const &URI, std::string const &Dist, bool const Trusted) :
+ metaIndex(URI, Dist, "deb"), d(new debReleaseIndexPrivate()) {
SetTrusted(Trusted);
}
-
debReleaseIndex::~debReleaseIndex() {
- for (map<string, vector<debSectionEntry const*> >::const_iterator A = ArchEntries.begin();
- A != ArchEntries.end(); ++A)
- for (vector<const debSectionEntry *>::const_iterator S = A->second.begin();
- S != A->second.end(); ++S)
- delete *S;
+ if (d != NULL)
+ delete d;
}
-
-template<typename CallC>
-void foreachTarget(std::string const &URI, std::string const &Dist,
- std::map<std::string, std::vector<debReleaseIndex::debSectionEntry const *> > const &ArchEntries,
- CallC &Call)
+ /*}}}*/
+// ReleaseIndex::GetIndexTargets /*{{{*/
+static void GetIndexTargetsFor(char const * const Type, std::string const &URI, std::string const &Dist,
+ std::vector<debReleaseIndexPrivate::debSectionEntry> const &entries,
+ std::vector<IndexTarget> &IndexTargets)
{
bool const flatArchive = (Dist[Dist.length() - 1] == '/');
std::string baseURI = URI;
@@ -118,148 +128,101 @@ void foreachTarget(std::string const &URI, std::string const &Dist,
baseURI += "dists/" + Dist + "/";
std::string const Release = (Dist == "/") ? "" : Dist;
std::string const Site = ::URI::ArchiveOnly(URI);
- std::vector<std::string> lang = APT::Configuration::getLanguages(true);
- if (lang.empty())
- lang.push_back("none");
- map<string, vector<debReleaseIndex::debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source");
- if (src != ArchEntries.end())
+
+ for (std::vector<debReleaseIndexPrivate::debSectionEntry>::const_iterator E = entries.begin(); E != entries.end(); ++E)
{
- std::vector<std::string> const targets = _config->FindVector("APT::Acquire::Targets::deb-src", "", true);
- for (std::vector<std::string>::const_iterator T = targets.begin(); T != targets.end(); ++T)
+ for (std::vector<std::string>::const_iterator T = E->Targets.begin(); T != E->Targets.end(); ++T)
{
-#define APT_T_CONFIG(X) _config->Find(std::string("APT::Acquire::Targets::deb-src::") + *T + "::" + (X))
- std::string const MetaKey = APT_T_CONFIG(flatArchive ? "flatMetaKey" : "MetaKey");
- std::string const ShortDesc = APT_T_CONFIG("ShortDescription");
- std::string const LongDesc = APT_T_CONFIG(flatArchive ? "flatDescription" : "Description");
+#define APT_T_CONFIG(X) _config->Find(std::string("APT::Acquire::Targets::") + Type + "::" + *T + "::" + (X))
+ std::string const tplMetaKey = APT_T_CONFIG(flatArchive ? "flatMetaKey" : "MetaKey");
+ std::string const tplShortDesc = APT_T_CONFIG("ShortDescription");
+ std::string const tplLongDesc = APT_T_CONFIG(flatArchive ? "flatDescription" : "Description");
bool const IsOptional = _config->FindB(std::string("APT::Acquire::Targets::deb-src::") + *T + "::Optional", true);
#undef APT_T_CONFIG
- if (MetaKey.empty())
+ if (tplMetaKey.empty())
continue;
- vector<debReleaseIndex::debSectionEntry const*> const SectionEntries = src->second;
- for (vector<debReleaseIndex::debSectionEntry const*>::const_iterator I = SectionEntries.begin();
- I != SectionEntries.end(); ++I)
+ for (std::vector<std::string>::const_iterator L = E->Languages.begin(); L != E->Languages.end(); ++L)
{
- for (vector<std::string>::const_iterator l = lang.begin(); l != lang.end(); ++l)
+ if (*L == "none" && tplMetaKey.find("$(LANGUAGE)") != std::string::npos)
+ continue;
+
+ for (std::vector<std::string>::const_iterator A = E->Architectures.begin(); A != E->Architectures.end(); ++A)
{
- if (*l == "none" && MetaKey.find("$(LANGUAGE)") != std::string::npos)
- continue;
std::map<std::string, std::string> Options;
Options.insert(std::make_pair("SITE", Site));
Options.insert(std::make_pair("RELEASE", Release));
- if (MetaKey.find("$(COMPONENT)") != std::string::npos)
- Options.insert(std::make_pair("COMPONENT", (*I)->Section));
- if (MetaKey.find("$(LANGUAGE)") != std::string::npos)
- Options.insert(std::make_pair("LANGUAGE", *l));
- Options.insert(std::make_pair("ARCHITECTURE", "source"));
+ if (tplMetaKey.find("$(COMPONENT)") != std::string::npos)
+ Options.insert(std::make_pair("COMPONENT", E->Name));
+ if (tplMetaKey.find("$(LANGUAGE)") != std::string::npos)
+ Options.insert(std::make_pair("LANGUAGE", *L));
+ if (tplMetaKey.find("$(ARCHITECTURE)") != std::string::npos)
+ Options.insert(std::make_pair("ARCHITECTURE", *A));
Options.insert(std::make_pair("BASE_URI", baseURI));
Options.insert(std::make_pair("REPO_URI", URI));
Options.insert(std::make_pair("TARGET_OF", "deb-src"));
Options.insert(std::make_pair("CREATED_BY", *T));
- Call(MetaKey, ShortDesc, LongDesc, IsOptional, Options);
- if (MetaKey.find("$(LANGUAGE)") == std::string::npos)
+ std::string MetaKey = tplMetaKey;
+ std::string ShortDesc = tplShortDesc;
+ std::string LongDesc = tplLongDesc;
+ for (std::map<std::string, std::string>::const_iterator O = Options.begin(); O != Options.end(); ++O)
+ {
+ MetaKey = SubstVar(MetaKey, std::string("$(") + O->first + ")", O->second);
+ ShortDesc = SubstVar(ShortDesc, std::string("$(") + O->first + ")", O->second);
+ LongDesc = SubstVar(LongDesc, std::string("$(") + O->first + ")", O->second);
+ }
+ IndexTarget Target(
+ MetaKey,
+ ShortDesc,
+ LongDesc,
+ Options.find("BASE_URI")->second + MetaKey,
+ IsOptional,
+ Options
+ );
+ IndexTargets.push_back(Target);
+
+ if (tplMetaKey.find("$(ARCHITECTURE)") == std::string::npos)
break;
- }
-
- if (MetaKey.find("$(COMPONENT)") == std::string::npos)
- break;
- }
- }
- }
-
- std::vector<std::string> const targets = _config->FindVector("APT::Acquire::Targets::deb", "", true);
- for (std::vector<std::string>::const_iterator T = targets.begin(); T != targets.end(); ++T)
- {
-#define APT_T_CONFIG(X) _config->Find(std::string("APT::Acquire::Targets::deb::") + *T + "::" + (X))
- std::string const MetaKey = APT_T_CONFIG(flatArchive ? "flatMetaKey" : "MetaKey");
- std::string const ShortDesc = APT_T_CONFIG("ShortDescription");
- std::string const LongDesc = APT_T_CONFIG(flatArchive ? "flatDescription" : "Description");
- bool const IsOptional = _config->FindB(std::string("APT::Acquire::Targets::deb::") + *T + "::Optional", true);
-#undef APT_T_CONFIG
- if (MetaKey.empty())
- continue;
-
- for (map<string, vector<debReleaseIndex::debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
- a != ArchEntries.end(); ++a)
- {
- if (a->first == "source")
- continue;
-
- for (vector <const debReleaseIndex::debSectionEntry *>::const_iterator I = a->second.begin();
- I != a->second.end(); ++I) {
-
- for (vector<std::string>::const_iterator l = lang.begin(); l != lang.end(); ++l)
- {
- if (*l == "none" && MetaKey.find("$(LANGUAGE)") != std::string::npos)
- continue;
-
- std::map<std::string, std::string> Options;
- Options.insert(std::make_pair("SITE", Site));
- Options.insert(std::make_pair("RELEASE", Release));
- if (MetaKey.find("$(COMPONENT)") != std::string::npos)
- Options.insert(std::make_pair("COMPONENT", (*I)->Section));
- if (MetaKey.find("$(LANGUAGE)") != std::string::npos)
- Options.insert(std::make_pair("LANGUAGE", *l));
- if (MetaKey.find("$(ARCHITECTURE)") != std::string::npos)
- Options.insert(std::make_pair("ARCHITECTURE", a->first));
- Options.insert(std::make_pair("BASE_URI", baseURI));
- Options.insert(std::make_pair("REPO_URI", URI));
- Options.insert(std::make_pair("TARGET_OF", "deb"));
- Options.insert(std::make_pair("CREATED_BY", *T));
- Call(MetaKey, ShortDesc, LongDesc, IsOptional, Options);
- if (MetaKey.find("$(LANGUAGE)") == std::string::npos)
- break;
}
- if (MetaKey.find("$(COMPONENT)") == std::string::npos)
+ if (tplMetaKey.find("$(LANGUAGE)") == std::string::npos)
break;
+
}
- if (MetaKey.find("$(ARCHITECTURE)") == std::string::npos)
- break;
}
}
}
-
-
-struct ComputeIndexTargetsClass
-{
- vector <IndexTarget> IndexTargets;
-
- void operator()(std::string MetaKey, std::string ShortDesc, std::string LongDesc,
- bool const IsOptional, std::map<std::string, std::string> Options)
- {
- for (std::map<std::string, std::string>::const_iterator O = Options.begin(); O != Options.end(); ++O)
- {
- MetaKey = SubstVar(MetaKey, std::string("$(") + O->first + ")", O->second);
- ShortDesc = SubstVar(ShortDesc, std::string("$(") + O->first + ")", O->second);
- LongDesc = SubstVar(LongDesc, std::string("$(") + O->first + ")", O->second);
- }
- IndexTarget Target(
- MetaKey,
- ShortDesc,
- LongDesc,
- Options.find("BASE_URI")->second + MetaKey,
- IsOptional,
- Options
- );
- IndexTargets.push_back(Target);
- }
-};
-
std::vector<IndexTarget> debReleaseIndex::GetIndexTargets() const
{
- ComputeIndexTargetsClass comp;
- foreachTarget(URI, Dist, ArchEntries, comp);
- return comp.IndexTargets;
+ std::vector<IndexTarget> IndexTargets;
+ GetIndexTargetsFor("deb-src", URI, Dist, d->DebSrcEntries, IndexTargets);
+ GetIndexTargetsFor("deb", URI, Dist, d->DebEntries, IndexTargets);
+ return IndexTargets;
}
+ /*}}}*/
+void debReleaseIndex::AddComponent(bool const isSrc, std::string const &Name,/*{{{*/
+ std::vector<std::string> const &Targets,
+ std::vector<std::string> const &Architectures,
+ std::vector<std::string> Languages)
+{
+ if (Languages.empty() == true)
+ Languages.push_back("none");
+ debReleaseIndexPrivate::debSectionEntry const entry = {
+ Name, Targets, Architectures, Languages
+ };
+ if (isSrc)
+ d->DebSrcEntries.push_back(entry);
+ else
+ d->DebEntries.push_back(entry);
+}
+ /*}}}*/
- /*}}}*/
-bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
+bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const/*{{{*/
{
indexRecords * const iR = new indexRecords(Dist);
if (Trusted == ALWAYS_TRUSTED)
@@ -282,7 +245,8 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
return true;
}
-
+ /*}}}*/
+// ReleaseIndex::*Trusted setters and checkers /*{{{*/
void debReleaseIndex::SetTrusted(bool const Trusted)
{
if (Trusted == true)
@@ -290,7 +254,6 @@ void debReleaseIndex::SetTrusted(bool const Trusted)
else
this->Trusted = NEVER_TRUSTED;
}
-
bool debReleaseIndex::IsTrusted() const
{
if (Trusted == ALWAYS_TRUSTED)
@@ -303,19 +266,13 @@ bool debReleaseIndex::IsTrusted() const
if(URI.substr(0,strlen("cdrom:")) == "cdrom:")
return true;
- string VerifiedSigFile = _config->FindDir("Dir::State::lists") +
- URItoFileName(MetaIndexURI("Release")) + ".gpg";
-
- if (FileExists(VerifiedSigFile))
+ if (FileExists(MetaIndexFile("Release.gpg")))
return true;
- VerifiedSigFile = _config->FindDir("Dir::State::lists") +
- URItoFileName(MetaIndexURI("InRelease"));
-
- return FileExists(VerifiedSigFile);
+ return FileExists(MetaIndexFile("InRelease"));
}
-
-std::vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles()
+ /*}}}*/
+std::vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() /*{{{*/
{
if (Indexes != NULL)
return Indexes;
@@ -335,23 +292,9 @@ std::vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles()
}
return Indexes;
}
+ /*}}}*/
-void debReleaseIndex::PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry) {
- for (vector<string>::const_iterator a = Archs.begin();
- a != Archs.end(); ++a)
- ArchEntries[*a].push_back(new debSectionEntry(Entry->Section, Entry->IsSrc));
- delete Entry;
-}
-
-void debReleaseIndex::PushSectionEntry(string const &Arch, const debSectionEntry *Entry) {
- ArchEntries[Arch].push_back(Entry);
-}
-
-debReleaseIndex::debSectionEntry::debSectionEntry (string const &Section,
- bool const &IsSrc): Section(Section), IsSrc(IsSrc)
-{}
-
-static bool ReleaseFileName(debReleaseIndex const * const That, std::string &ReleaseFile)
+static bool ReleaseFileName(debReleaseIndex const * const That, std::string &ReleaseFile)/*{{{*/
{
ReleaseFile = That->MetaIndexFile("InRelease");
bool releaseExists = false;
@@ -365,7 +308,7 @@ static bool ReleaseFileName(debReleaseIndex const * const That, std::string &Rel
}
return releaseExists;
}
-
+ /*}}}*/
bool debReleaseIndex::Merge(pkgCacheGenerator &Gen,OpProgress * /*Prog*/) const/*{{{*/
{
std::string ReleaseFile;
@@ -459,46 +402,46 @@ pkgCache::RlsFileIterator debReleaseIndex::FindInCache(pkgCache &Cache, bool con
}
/*}}}*/
-debDebFileMetaIndex::~debDebFileMetaIndex() {}
-
-class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type
+static std::vector<std::string> parsePlusMinusOptions(std::string const &Name, /*{{{*/
+ std::map<std::string, std::string> const &Options, std::vector<std::string> const &defaultValues)
{
- protected:
+ std::map<std::string, std::string>::const_iterator val = Options.find(Name);
+ std::vector<std::string> Values;
+ if (val != Options.end())
+ Values = VectorizeString(val->second, ',');
+ else
+ Values = defaultValues;
- bool CreateItemInternal(vector<metaIndex *> &List, string const &URI,
- string const &Dist, string const &Section,
- bool const &IsSrc, map<string, string> const &Options) const
+ if ((val = Options.find(Name + "+")) != Options.end())
{
- // parse arch=, arch+= and arch-= settings
- map<string, string>::const_iterator arch = Options.find("arch");
- vector<string> Archs;
- if (arch != Options.end())
- Archs = VectorizeString(arch->second, ',');
- else
- Archs = APT::Configuration::getArchitectures();
-
- if ((arch = Options.find("arch+")) != Options.end())
- {
- std::vector<std::string> const plusArch = VectorizeString(arch->second, ',');
- for (std::vector<std::string>::const_iterator plus = plusArch.begin(); plus != plusArch.end(); ++plus)
- if (std::find(Archs.begin(), Archs.end(), *plus) == Archs.end())
- Archs.push_back(*plus);
- }
- if ((arch = Options.find("arch-")) != Options.end())
+ std::vector<std::string> const plusArch = VectorizeString(val->second, ',');
+ for (std::vector<std::string>::const_iterator plus = plusArch.begin(); plus != plusArch.end(); ++plus)
+ if (std::find(Values.begin(), Values.end(), *plus) == Values.end())
+ Values.push_back(*plus);
+ }
+ if ((val = Options.find(Name + "-")) != Options.end())
+ {
+ std::vector<std::string> const minusArch = VectorizeString(val->second, ',');
+ for (std::vector<std::string>::const_iterator minus = minusArch.begin(); minus != minusArch.end(); ++minus)
{
- std::vector<std::string> const minusArch = VectorizeString(arch->second, ',');
- for (std::vector<std::string>::const_iterator minus = minusArch.begin(); minus != minusArch.end(); ++minus)
- {
- std::vector<std::string>::iterator kill = std::find(Archs.begin(), Archs.end(), *minus);
- if (kill != Archs.end())
- Archs.erase(kill);
- }
+ std::vector<std::string>::iterator kill = std::find(Values.begin(), Values.end(), *minus);
+ if (kill != Values.end())
+ Values.erase(kill);
}
+ }
+ return Values;
+}
+ /*}}}*/
+class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/
+{
+ protected:
- map<string, string>::const_iterator const trusted = Options.find("trusted");
-
+ bool CreateItemInternal(std::vector<metaIndex *> &List, std::string const &URI,
+ std::string const &Dist, std::string const &Section,
+ bool const &IsSrc, std::map<std::string, std::string> const &Options) const
+ {
debReleaseIndex *Deb = NULL;
- for (vector<metaIndex *>::const_iterator I = List.begin();
+ for (std::vector<metaIndex *>::const_iterator I = List.begin();
I != List.end(); ++I)
{
// We only worry about debian entries here
@@ -523,87 +466,86 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type
List.push_back(Deb);
}
- if (IsSrc == true)
- Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc));
- else
- {
- if (Dist[Dist.size() - 1] == '/')
- Deb->PushSectionEntry ("any", new debReleaseIndex::debSectionEntry(Section, IsSrc));
- else
- Deb->PushSectionEntry (Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc));
- }
+ Deb->AddComponent(
+ IsSrc,
+ Section,
+ parsePlusMinusOptions("target", Options, _config->FindVector(std::string("APT::Acquire::Targets::") + Name, "", true)),
+ parsePlusMinusOptions("arch", Options, APT::Configuration::getArchitectures()),
+ parsePlusMinusOptions("lang", Options, APT::Configuration::getLanguages(true))
+ );
+ std::map<std::string, std::string>::const_iterator const trusted = Options.find("trusted");
if (trusted != Options.end())
Deb->SetTrusted(StringToBool(trusted->second, false));
return true;
}
-};
-
-debDebFileMetaIndex::debDebFileMetaIndex(std::string const &DebFile)
- : metaIndex(DebFile, "local-uri", "deb-dist"), d(NULL), DebFile(DebFile)
-{
- DebIndex = new debDebPkgFileIndex(DebFile);
- Indexes = new vector<pkgIndexFile *>();
- Indexes->push_back(DebIndex);
-}
-
-class APT_HIDDEN debSLTypeDeb : public debSLTypeDebian
+ debSLTypeDebian(char const * const Name, char const * const Label) : Type(Name, Label)
+ {
+ }
+};
+ /*}}}*/
+class APT_HIDDEN debSLTypeDeb : public debSLTypeDebian /*{{{*/
{
public:
- bool CreateItem(vector<metaIndex *> &List, string const &URI,
- string const &Dist, string const &Section,
- std::map<string, string> const &Options) const
+ bool CreateItem(std::vector<metaIndex *> &List, std::string const &URI,
+ std::string const &Dist, std::string const &Section,
+ std::map<std::string, std::string> const &Options) const
{
return CreateItemInternal(List, URI, Dist, Section, false, Options);
}
- debSLTypeDeb()
+ debSLTypeDeb() : debSLTypeDebian("deb", "Debian binary tree")
{
- Name = "deb";
- Label = "Standard Debian binary tree";
- }
+ }
};
-
-class APT_HIDDEN debSLTypeDebSrc : public debSLTypeDebian
+ /*}}}*/
+class APT_HIDDEN debSLTypeDebSrc : public debSLTypeDebian /*{{{*/
{
public:
- bool CreateItem(vector<metaIndex *> &List, string const &URI,
- string const &Dist, string const &Section,
- std::map<string, string> const &Options) const
+ bool CreateItem(std::vector<metaIndex *> &List, std::string const &URI,
+ std::string const &Dist, std::string const &Section,
+ std::map<std::string, std::string> const &Options) const
{
return CreateItemInternal(List, URI, Dist, Section, true, Options);
}
-
- debSLTypeDebSrc()
+
+ debSLTypeDebSrc() : debSLTypeDebian("deb-src", "Debian source tree")
{
- Name = "deb-src";
- Label = "Standard Debian source tree";
- }
+ }
};
+ /*}}}*/
-class APT_HIDDEN debSLTypeDebFile : public pkgSourceList::Type
+debDebFileMetaIndex::debDebFileMetaIndex(std::string const &DebFile) /*{{{*/
+ : metaIndex(DebFile, "local-uri", "deb-dist"), d(NULL), DebFile(DebFile)
+{
+ DebIndex = new debDebPkgFileIndex(DebFile);
+ Indexes = new std::vector<pkgIndexFile *>();
+ Indexes->push_back(DebIndex);
+}
+debDebFileMetaIndex::~debDebFileMetaIndex() {}
+ /*}}}*/
+class APT_HIDDEN debSLTypeDebFile : public pkgSourceList::Type /*{{{*/
{
public:
- bool CreateItem(vector<metaIndex *> &List, string const &URI,
- string const &/*Dist*/, string const &/*Section*/,
- std::map<string, string> const &/*Options*/) const
+ bool CreateItem(std::vector<metaIndex *> &List, std::string const &URI,
+ std::string const &/*Dist*/, std::string const &/*Section*/,
+ std::map<std::string, std::string> const &/*Options*/) const
{
metaIndex *mi = new debDebFileMetaIndex(URI);
List.push_back(mi);
return true;
}
-
- debSLTypeDebFile()
+
+ debSLTypeDebFile() : Type("deb-file", "Debian local deb file")
{
- Name = "deb-file";
- Label = "Debian Deb File";
- }
+ }
};
+ /*}}}*/
APT_HIDDEN debSLTypeDeb _apt_DebType;
APT_HIDDEN debSLTypeDebSrc _apt_DebSrcType;
diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h
index 648c22436..9b60b6137 100644
--- a/apt-pkg/deb/debmetaindex.h
+++ b/apt-pkg/deb/debmetaindex.h
@@ -1,4 +1,3 @@
-// ijones, walters
#ifndef PKGLIB_DEBMETAINDEX_H
#define PKGLIB_DEBMETAINDEX_H
@@ -22,26 +21,20 @@ class debDebPkgFileIndex;
class IndexTarget;
class pkgCacheGenerator;
class OpProgress;
+class debReleaseIndexPrivate;
-class APT_HIDDEN debReleaseIndex : public metaIndex {
- public:
+class APT_HIDDEN debReleaseIndex : public metaIndex
+{
+ debReleaseIndexPrivate * const d;
- class debSectionEntry
- {
- public:
- debSectionEntry (std::string const &Section, bool const &IsSrc);
- std::string const Section;
- bool const IsSrc;
- };
-
- private:
- /** \brief dpointer placeholder (for later in case we need it) */
- void * const d;
- std::map<std::string, std::vector<debSectionEntry const*> > ArchEntries;
enum APT_HIDDEN { ALWAYS_TRUSTED, NEVER_TRUSTED, CHECK_TRUST } Trusted;
public:
+ APT_HIDDEN std::string MetaIndexInfo(const char *Type) const;
+ APT_HIDDEN std::string MetaIndexFile(const char *Types) const;
+ APT_HIDDEN std::string MetaIndexURI(const char *Type) const;
+
debReleaseIndex(std::string const &URI, std::string const &Dist);
debReleaseIndex(std::string const &URI, std::string const &Dist, bool const Trusted);
virtual ~debReleaseIndex();
@@ -54,22 +47,17 @@ class APT_HIDDEN debReleaseIndex : public metaIndex {
virtual pkgCache::RlsFileIterator FindInCache(pkgCache &Cache, bool const ModifyCheck) const;
virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
- std::string MetaIndexInfo(const char *Type) const;
- std::string MetaIndexFile(const char *Types) const;
- std::string MetaIndexURI(const char *Type) const;
-
-#if APT_PKG_ABI >= 413
- virtual
-#endif
- std::string LocalFileName() const;
+ virtual std::string LocalFileName() const;
virtual std::vector <pkgIndexFile *> *GetIndexFiles();
void SetTrusted(bool const Trusted);
virtual bool IsTrusted() const;
- void PushSectionEntry(std::vector<std::string> const &Archs, const debSectionEntry *Entry);
- void PushSectionEntry(std::string const &Arch, const debSectionEntry *Entry);
+ void AddComponent(bool const isSrc, std::string const &Name,
+ std::vector<std::string> const &Targets,
+ std::vector<std::string> const &Architectures,
+ std::vector<std::string> Languages);
};
class APT_HIDDEN debDebFileMetaIndex : public metaIndex
diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc
index 99b646513..6ef99863d 100644
--- a/apt-pkg/sourcelist.cc
+++ b/apt-pkg/sourcelist.cc
@@ -37,25 +37,26 @@
using namespace std;
// Global list of Items supported
-static pkgSourceList::Type *ItmList[10];
+static pkgSourceList::Type *ItmList[10];
pkgSourceList::Type **pkgSourceList::Type::GlobalList = ItmList;
unsigned long pkgSourceList::Type::GlobalListLen = 0;
// Type::Type - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* Link this to the global list of items*/
-pkgSourceList::Type::Type() : Name(NULL), Label(NULL)
+pkgSourceList::Type::Type(char const * const pName, char const * const pLabel) : Name(pName), Label(pLabel)
{
ItmList[GlobalListLen] = this;
- GlobalListLen++;
+ ++GlobalListLen;
}
+pkgSourceList::Type::~Type() {}
/*}}}*/
// Type::GetType - Get a specific meta for a given type /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgSourceList::Type *pkgSourceList::Type::GetType(const char *Type)
{
- for (unsigned I = 0; I != GlobalListLen; I++)
+ for (unsigned I = 0; I != GlobalListLen; ++I)
if (strcmp(GlobalList[I]->Name,Type) == 0)
return GlobalList[I];
return 0;
@@ -91,23 +92,26 @@ bool pkgSourceList::Type::ParseStanza(vector<metaIndex *> &List,
string Enabled = Tags.FindS("Enabled");
if (Enabled.size() > 0 && StringToBool(Enabled) == false)
return true;
-
- // Define external/internal options
- const char* option_deb822[] = {
- "Architectures", "Architectures-Add", "Architectures-Remove", "Trusted",
- };
- const char* option_internal[] = {
- "arch", "arch+", "arch-", "trusted",
- };
- for (unsigned int j=0; j < sizeof(option_deb822)/sizeof(char*); j++)
- if (Tags.Exists(option_deb822[j]))
+
+ std::map<char const * const, char const * const> mapping;
+#define APT_PLUSMINUS(X, Y) \
+ mapping.insert(std::make_pair(X, Y)); \
+ mapping.insert(std::make_pair(X "Add", Y "+")); \
+ mapping.insert(std::make_pair(X "Remove", Y "-"))
+ APT_PLUSMINUS("Architectures", "arch");
+ APT_PLUSMINUS("Languages", "lang");
+ APT_PLUSMINUS("Targets", "target");
+#undef APT_PLUSMINUS
+ mapping.insert(std::make_pair("Trusted", "trusted"));
+ for (std::map<char const * const, char const * const>::const_iterator m = mapping.begin(); m != mapping.end(); ++m)
+ if (Tags.Exists(m->first))
{
// for deb822 the " " is the delimiter, but the backend expects ","
- std::string option = Tags.FindS(option_deb822[j]);
+ std::string option = Tags.FindS(m->first);
std::replace(option.begin(), option.end(), ' ', ',');
- Options[option_internal[j]] = option;
+ Options[m->second] = option;
}
-
+
// now create one item per suite/section
string Suite = Tags.FindS("Suites");
Suite = SubstVar(Suite,"$(ARCH)",_config->Find("APT::Architecture"));
@@ -209,7 +213,7 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
if (FixupURI(URI) == false)
return _error->Error(_("Malformed line %lu in source list %s (URI parse)"),CurLine,File.c_str());
-
+
// Check for an absolute dists specification.
if (Dist.empty() == false && Dist[Dist.size() - 1] == '/')
{
diff --git a/apt-pkg/sourcelist.h b/apt-pkg/sourcelist.h
index e17ad6a9a..4f42b3e91 100644
--- a/apt-pkg/sourcelist.h
+++ b/apt-pkg/sourcelist.h
@@ -66,8 +66,8 @@ class pkgSourceList
static unsigned long GlobalListLen;
static Type *GetType(const char *Type) APT_PURE;
- const char *Name;
- const char *Label;
+ char const * const Name;
+ char const * const Label;
bool FixupURI(std::string &URI) const;
virtual bool ParseStanza(std::vector<metaIndex *> &List,
@@ -80,8 +80,8 @@ class pkgSourceList
virtual bool CreateItem(std::vector<metaIndex *> &List,std::string const &URI,
std::string const &Dist,std::string const &Section,
std::map<std::string, std::string> const &Options) const = 0;
- Type();
- virtual ~Type() {};
+ Type(char const * const Name, char const * const Label);
+ virtual ~Type();
};
typedef std::vector<metaIndex *>::const_iterator const_iterator;
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index 632c7cfea..500a0a3c5 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -1045,7 +1045,7 @@ static bool DoBuildDep(CommandLine &CmdL)
{
ioprintf(c1out, _("Note, using directory '%s' to get the build dependencies\n"), *I);
// FIXME: how can we make this more elegant?
- std::string TypeName = "debian/control File Source Index";
+ std::string TypeName = "Debian control file";
pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str());
if(Type != NULL)
LastOwner = Last = Type->CreateSrcPkgParser(*I);
@@ -1056,7 +1056,7 @@ static bool DoBuildDep(CommandLine &CmdL)
ioprintf(c1out, _("Note, using file '%s' to get the build dependencies\n"), *I);
// see if we can get a parser for this pkgIndexFile type
- string TypeName = flExtension(*I) + " File Source Index";
+ string TypeName = "Debian " + flExtension(*I) + " file";
pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str());
if(Type != NULL)
LastOwner = Last = Type->CreateSrcPkgParser(*I);
diff --git a/doc/sources.list.5.xml b/doc/sources.list.5.xml
index da4f571b5..6ebba3528 100644
--- a/doc/sources.list.5.xml
+++ b/doc/sources.list.5.xml
@@ -137,9 +137,25 @@
can be used to specify for which architectures information should
be downloaded. If this option is not set all architectures defined by the
<literal>APT::Architectures</literal> option will be downloaded.</para></listitem>
+
<listitem><para><literal>arch+=<replaceable>arch1</replaceable>,<replaceable>arch2</replaceable>,…</literal>
and <literal>arch-=<replaceable>arch1</replaceable>,<replaceable>arch2</replaceable>,…</literal>
which can be used to add/remove architectures from the set which will be downloaded.</para></listitem>
+
+ <listitem><para><literal>lang=<replaceable>lang1</replaceable>,<replaceable>lang2</replaceable>,…</literal>,
+ <literal>lang+=<replaceable>lang1</replaceable>,<replaceable>lang2</replaceable>,…</literal> and
+ <literal>lang-=<replaceable>lang1</replaceable>,<replaceable>lang2</replaceable>,…</literal> functioning in
+ the same way as the <literal>arch</literal>-options described before. They can be used to specify for
+ which languages apt will acquire metadata, like translated package descriptions, for. If not specified, the
+ default set is defined by the <literal>Acquire::Languages</literal> config option.</para></listitem>
+
+ <listitem><para><literal>target=<replaceable>target1</replaceable>,<replaceable>target2</replaceable>,…</literal>,
+ <literal>target+=<replaceable>target1</replaceable>,<replaceable>target2</replaceable>,…</literal> and
+ <literal>target-=<replaceable>target1</replaceable>,<replaceable>target2</replaceable>,…</literal> again functioning in
+ the same way as the <literal>arch</literal>-options described before. They can be used to specify which
+ targets apt will try to acquire from this source. If not specified, the default set is defined by
+ the <literal>APT::Acquire::Targets</literal> configuration scope.</para></listitem>
+
<listitem><para><literal>trusted=yes</literal> can be set to indicate that packages
from this source are always authenticated even if the <filename>Release</filename> file
is not signed or the signature can't be checked. This disables parts of &apt-secure;
diff --git a/test/integration/test-bug-632221-cross-dependency-satisfaction b/test/integration/test-bug-632221-cross-dependency-satisfaction
index 563821173..12704e5de 100755
--- a/test/integration/test-bug-632221-cross-dependency-satisfaction
+++ b/test/integration/test-bug-632221-cross-dependency-satisfaction
@@ -167,17 +167,17 @@ Conf libfwibble-dev (1.0 unstable [armel])' aptget build-dep apt -s
testsuccessequal 'Reading package lists...
Building dependency tree...
The following NEW packages will be installed:
- amdboot:amd64 cool doxygen foreigner libc6:amd64 libc6 libc6-dev:amd64
- libc6-dev libfwibble-dev:amd64 libfwibble1:amd64 linux-stuff:amd64
+ amdboot:amd64 cool doxygen foreigner libc6 libc6:amd64 libc6-dev
+ libc6-dev:amd64 libfwibble-dev:amd64 libfwibble1:amd64 linux-stuff:amd64
0 upgraded, 11 newly installed, 0 to remove and 0 not upgraded.
Inst amdboot:amd64 (1.0 unstable [amd64])
Inst cool (1.0 unstable [armel])
Inst doxygen (1.0 unstable [armel])
Inst foreigner (1.0 unstable [armel])
-Inst libc6:amd64 (1.0 unstable [amd64])
Inst libc6 (1.0 unstable [armel])
-Inst libc6-dev:amd64 (1.0 unstable [amd64])
+Inst libc6:amd64 (1.0 unstable [amd64])
Inst libc6-dev (1.0 unstable [armel])
+Inst libc6-dev:amd64 (1.0 unstable [amd64])
Inst libfwibble1:amd64 (1.0 unstable [amd64])
Inst libfwibble-dev:amd64 (1.0 unstable [amd64])
Inst linux-stuff:amd64 (1.0 unstable [amd64])
@@ -185,10 +185,10 @@ Conf amdboot:amd64 (1.0 unstable [amd64])
Conf cool (1.0 unstable [armel])
Conf doxygen (1.0 unstable [armel])
Conf foreigner (1.0 unstable [armel])
-Conf libc6:amd64 (1.0 unstable [amd64])
Conf libc6 (1.0 unstable [armel])
-Conf libc6-dev:amd64 (1.0 unstable [amd64])
+Conf libc6:amd64 (1.0 unstable [amd64])
Conf libc6-dev (1.0 unstable [armel])
+Conf libc6-dev:amd64 (1.0 unstable [amd64])
Conf libfwibble1:amd64 (1.0 unstable [amd64])
Conf libfwibble-dev:amd64 (1.0 unstable [amd64])
Conf linux-stuff:amd64 (1.0 unstable [amd64])' aptget build-dep apt -s -a amd64
@@ -275,24 +275,24 @@ Conf libfwibble-dev (1.0 unstable [armel])' aptget build-dep apt -s
testsuccessequal 'Reading package lists...
Building dependency tree...
The following NEW packages will be installed:
- amdboot:amd64 doxygen libc6:amd64 libc6 libc6-dev:amd64 libc6-dev
+ amdboot:amd64 doxygen libc6 libc6:amd64 libc6-dev libc6-dev:amd64
libfwibble-dev:amd64 libfwibble1:amd64 linux-stuff:amd64
0 upgraded, 9 newly installed, 0 to remove and 2 not upgraded.
Inst amdboot:amd64 (1.0 unstable [amd64])
Inst doxygen (1.0 unstable [armel])
-Inst libc6:amd64 (1.0 unstable [amd64])
Inst libc6 (1.0 unstable [armel])
-Inst libc6-dev:amd64 (1.0 unstable [amd64])
+Inst libc6:amd64 (1.0 unstable [amd64])
Inst libc6-dev (1.0 unstable [armel])
+Inst libc6-dev:amd64 (1.0 unstable [amd64])
Inst libfwibble1:amd64 (1.0 unstable [amd64])
Inst libfwibble-dev:amd64 (1.0 unstable [amd64])
Inst linux-stuff:amd64 (1.0 unstable [amd64])
Conf amdboot:amd64 (1.0 unstable [amd64])
Conf doxygen (1.0 unstable [armel])
-Conf libc6:amd64 (1.0 unstable [amd64])
Conf libc6 (1.0 unstable [armel])
-Conf libc6-dev:amd64 (1.0 unstable [amd64])
+Conf libc6:amd64 (1.0 unstable [amd64])
Conf libc6-dev (1.0 unstable [armel])
+Conf libc6-dev:amd64 (1.0 unstable [amd64])
Conf libfwibble1:amd64 (1.0 unstable [amd64])
Conf libfwibble-dev:amd64 (1.0 unstable [amd64])
Conf linux-stuff:amd64 (1.0 unstable [amd64])' aptget build-dep apt -s -a amd64
diff --git a/test/integration/test-ignore-provides-if-versioned-breaks b/test/integration/test-ignore-provides-if-versioned-breaks
index 20424b942..4d6114637 100755
--- a/test/integration/test-ignore-provides-if-versioned-breaks
+++ b/test/integration/test-ignore-provides-if-versioned-breaks
@@ -134,17 +134,17 @@ Conf foo-same-provider (1.0 unstable [i386])' aptget install foo-same-provider f
testsuccessequal 'Reading package lists...
Building dependency tree...
The following extra packages will be installed:
- foo-same:amd64 foo-same
+ foo-same foo-same:amd64
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
+ foo-same foo-same:amd64
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])
+Inst foo-same [2.0] (4.0 unstable [i386]) [foo-same:i386 on foo-same:amd64] [foo-same:amd64 on foo-same:i386] [foo-same:amd64 ]
+Inst foo-same:amd64 [2.0] (4.0 unstable [amd64])
Inst foo-same-breaker-3 (1.0 unstable [i386])
Inst foo-same-provider (1.0 unstable [i386])
-Conf foo-same (4.0 unstable [i386])
Conf foo-same:amd64 (4.0 unstable [amd64])
+Conf foo-same (4.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
index a781d8e44..6a0c924e2 100755
--- a/test/integration/test-ignore-provides-if-versioned-conflicts
+++ b/test/integration/test-ignore-provides-if-versioned-conflicts
@@ -134,17 +134,17 @@ Conf foo-same-provider (1.0 unstable [i386])' aptget install foo-same-provider f
testsuccessequal 'Reading package lists...
Building dependency tree...
The following extra packages will be installed:
- foo-same:amd64 foo-same
+ foo-same foo-same:amd64
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
+ foo-same foo-same:amd64
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])
+Inst foo-same [2.0] (4.0 unstable [i386]) [foo-same:i386 on foo-same:amd64] [foo-same:amd64 on foo-same:i386] [foo-same:amd64 ]
+Inst foo-same:amd64 [2.0] (4.0 unstable [amd64])
Inst foo-same-breaker-3 (1.0 unstable [i386])
Inst foo-same-provider (1.0 unstable [i386])
-Conf foo-same (4.0 unstable [i386])
Conf foo-same:amd64 (4.0 unstable [amd64])
+Conf foo-same (4.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-sourceslist-lang-plusminus-options b/test/integration/test-sourceslist-lang-plusminus-options
new file mode 100755
index 000000000..28d5f9e06
--- /dev/null
+++ b/test/integration/test-sourceslist-lang-plusminus-options
@@ -0,0 +1,87 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'native'
+
+testlangs() {
+ msgtest 'Test acquired languages for' "$1"
+ local LANGS="$2"
+ shift 2
+ rm -f gotlangs.list
+ aptget files --no-release-info 'Created-By: Translations' "$@" --format '$(LANGUAGE)' | sort -u > gotlangs.list
+ if [ -z "$LANGS" ]; then
+ echo -n | tr ',' '\n' | sort | checkdiff - gotlangs.list && msgpass || msgfail
+ else
+ echo -n "$LANGS" | tr ',' '\n' | sort | checkdiff - gotlangs.list && msgpass || msgfail
+ fi
+}
+echo 'deb http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testlangs 'default' 'en'
+
+echo 'Acquire::Languages "environment,en";' > rootdir/etc/apt/apt.conf.d/langs.conf
+testlangs 'default config' 'en'
+
+echo 'Acquire::Languages "en,en,en";' > rootdir/etc/apt/apt.conf.d/langs.conf
+testlangs 'duplicated config' 'en'
+
+echo 'Acquire::Languages "none";' > rootdir/etc/apt/apt.conf.d/langs.conf
+testlangs 'none config' ''
+
+echo 'Acquire::Languages "en,none,de,de_DE";' > rootdir/etc/apt/apt.conf.d/langs.conf
+testlangs 'english + german config' 'en,de,de_DE'
+
+echo 'deb [lang=pt] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testlangs 'lang=pt' 'pt'
+
+echo 'deb [lang=en] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testlangs 'lang=en' 'en'
+
+echo 'deb [lang=de_DE] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testlangs 'lang=de_DE' 'de_DE'
+
+echo 'deb [lang=none] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testlangs 'lang=none' ''
+testequal 'amd64' aptget files --no-release-info 'Created-By: Packages' --format '$(ARCHITECTURE)'
+
+echo 'deb [lang+=pt] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testlangs 'lang+=pt' 'en,de,de_DE,pt'
+
+echo 'deb [lang+=en] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testlangs 'lang+=en' 'en,de,de_DE'
+
+echo 'deb [lang+=de_DE] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testlangs 'lang+=de_DE' 'en,de,de_DE'
+
+echo 'deb [lang-=pt] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testlangs 'lang-=pt' 'en,de,de_DE'
+
+echo 'deb [lang-=en] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testlangs 'lang-=en' 'de,de_DE'
+
+echo 'deb [lang-=de_DE] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testlangs 'lang-=de_DE' 'en,de'
+
+echo 'deb http://example.org/debian stable rocks
+deb http://example.org/debian stable solid' > rootdir/etc/apt/sources.list
+testlangs 'english + german config multicomponent' 'en,de,de_DE'
+
+echo 'deb http://example.org/debian stable rocks
+deb [lang=pt] http://example.org/debian stable solid' > rootdir/etc/apt/sources.list
+testlangs 'multicomponent one lang= combined' 'en,de,de_DE,pt'
+testlangs 'multicomponent one lang= rocks' 'en,de,de_DE' 'Component: rocks'
+testlangs 'multicomponent one lang= solid' 'pt' 'Component: solid'
+
+echo 'deb [lang=pt] http://example.org/debian stable rocks
+deb [lang=de] http://example.org/debian stable solid' > rootdir/etc/apt/sources.list
+testlangs 'multicomponent different lang= combined' 'de,pt'
+testlangs 'multicomponent different lang= rocks' 'pt' 'Component: rocks'
+testlangs 'multicomponent different lang= solid' 'de' 'Component: solid'
+
+echo 'deb [lang+=pt] http://example.org/debian stable rocks
+deb [lang-=de] http://example.org/debian stable solid' > rootdir/etc/apt/sources.list
+testlangs 'multicomponent different lang+-= combined' 'en,de,de_DE,pt'
+testlangs 'multicomponent different lang+-= rocks' 'en,de,de_DE,pt' 'Component: rocks'
+testlangs 'multicomponent different lang+-= solid' 'en,de_DE' 'Component: solid'