X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/7c1dca1439b956a085b09c73fdbe5a66af20241b..5b0577488ff60e7163fe7dc62a044329d398d726:/apt-pkg/deb/debmetaindex.cc diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 260686cc7..aad7df735 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -33,13 +33,13 @@ class APT_HIDDEN debReleaseIndexPrivate /*{{{*/ public: struct APT_HIDDEN debSectionEntry { - std::string sourcesEntry; - std::string Name; - std::vector Targets; - std::vector Architectures; - std::vector Languages; - bool UsePDiffs; - std::string UseByHash; + std::string const sourcesEntry; + std::string const Name; + std::vector const Targets; + std::vector const Architectures; + std::vector const Languages; + bool const UsePDiffs; + std::string const UseByHash; }; std::vector DebEntries; @@ -165,6 +165,7 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI, std::string const tplMetaKey = APT_T_CONFIG_STR(flatArchive ? "flatMetaKey" : "MetaKey", ""); std::string const tplShortDesc = APT_T_CONFIG_STR("ShortDescription", ""); std::string const tplLongDesc = "$(SITE) " + APT_T_CONFIG_STR(flatArchive ? "flatDescription" : "Description", ""); + std::string const tplIdentifier = APT_T_CONFIG_STR("Identifier", *T); bool const IsOptional = APT_T_CONFIG_BOOL("Optional", true); bool const KeepCompressed = APT_T_CONFIG_BOOL("KeepCompressed", GzipIndex); bool const DefaultEnabled = APT_T_CONFIG_BOOL("DefaultEnabled", true); @@ -172,6 +173,7 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI, std::string const UseByHash = APT_T_CONFIG_STR("By-Hash", E->UseByHash); std::string const CompressionTypes = APT_T_CONFIG_STR("CompressionTypes", DefCompressionTypes); std::string KeepCompressedAs = APT_T_CONFIG_STR("KeepCompressedAs", ""); + std::string const FallbackOf = APT_T_CONFIG_STR("Fallback-Of", ""); #undef APT_T_CONFIG_BOOL #undef APT_T_CONFIG_STR if (tplMetaKey.empty()) @@ -228,11 +230,14 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI, std::string MetaKey = tplMetaKey; std::string ShortDesc = tplShortDesc; std::string LongDesc = tplLongDesc; + std::string Identifier = tplIdentifier; for (std::map::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); + std::string const varname = "$(" + O->first + ")"; + MetaKey = SubstVar(MetaKey, varname, O->second); + ShortDesc = SubstVar(ShortDesc, varname, O->second); + LongDesc = SubstVar(LongDesc, varname, O->second); + Identifier = SubstVar(Identifier, varname, O->second); } { @@ -290,8 +295,10 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI, // not available in templates, but in the indextarget Options.insert(std::make_pair("BASE_URI", baseURI)); Options.insert(std::make_pair("REPO_URI", URI)); + Options.insert(std::make_pair("IDENTIFIER", Identifier)); Options.insert(std::make_pair("TARGET_OF", Type)); Options.insert(std::make_pair("CREATED_BY", *T)); + Options.insert(std::make_pair("FALLBACK_OF", FallbackOf)); Options.insert(std::make_pair("PDIFFS", UsePDiffs ? "yes" : "no")); Options.insert(std::make_pair("BY_HASH", UseByHash)); Options.insert(std::make_pair("DEFAULTENABLED", DefaultEnabled ? "yes" : "no")); @@ -616,7 +623,8 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll)/*{{{*/ // special case for --print-uris if (GetAll) for (auto const &Target: GetIndexTargets()) - new pkgAcqIndex(Owner, TransactionManager, Target); + if (Target.Option(IndexTarget::FALLBACK_OF).empty()) + new pkgAcqIndex(Owner, TransactionManager, Target); return true; } @@ -679,6 +687,8 @@ bool debReleaseIndex::SetSignedBy(std::string const &pSignedBy) std::stringstream os; std::copy(fingers.begin(), fingers.end(), std::ostream_iterator(os, ",")); SignedBy = os.str(); + while (SignedBy[SignedBy.size() - 1] == ',') + SignedBy.resize(SignedBy.size() - 1); } } else if (SignedBy != pSignedBy) @@ -942,12 +952,40 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/ std::map::const_iterator const opt = Options.find(target); if (opt == Options.end()) continue; - auto const tarItr = std::find(mytargets.begin(), mytargets.end(), target); - bool const optValue = StringToBool(opt->second); - if (optValue == true && tarItr == mytargets.end()) - mytargets.push_back(target); - else if (optValue == false && tarItr != mytargets.end()) - mytargets.erase(std::remove(mytargets.begin(), mytargets.end(), target), mytargets.end()); + auto const idMatch = [&](std::string const &t) { + return target == _config->Find(std::string("Acquire::IndexTargets::") + Name + "::" + t + "::Identifier", t); + }; + if (StringToBool(opt->second)) + std::copy_if(alltargets.begin(), alltargets.end(), std::back_inserter(mytargets), idMatch); + else + mytargets.erase(std::remove_if(mytargets.begin(), mytargets.end(), idMatch), mytargets.end()); + } + // if we can't order it in a 1000 steps we give up… probably a cycle + for (auto i = 0; i < 1000; ++i) + { + bool Changed = false; + for (auto t = mytargets.begin(); t != mytargets.end(); ++t) + { + std::string const fallback = _config->Find(std::string("Acquire::IndexTargets::") + Name + "::" + *t + "::Fallback-Of"); + if (fallback.empty()) + continue; + auto const faller = std::find(mytargets.begin(), mytargets.end(), fallback); + if (faller == mytargets.end() || faller < t) + continue; + Changed = true; + auto const tv = *t; + mytargets.erase(t); + mytargets.emplace_back(tv); + } + if (Changed == false) + break; + } + // remove duplicates without changing the order (in first appearance) + { + std::set seenOnce; + mytargets.erase(std::remove_if(mytargets.begin(), mytargets.end(), [&](std::string const &t) { + return seenOnce.insert(t).second == false; + }), mytargets.end()); } bool UsePDiffs = _config->FindB("Acquire::PDiffs", true);