X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/d03b947b0ce4f87d7d5cc48d4d274ab3bd0b289a..15e1ed52a741ff82deb0a4cd6150cf10e23b7368:/apt-pkg/deb/debmetaindex.cc diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 2671fc30d..8d84409a1 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -147,7 +147,7 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI, DefKeepCompressedAs += "uncompressed"; } - std::vector const NativeArchs = { _config->Find("APT::Architecture"), "all" }; + std::vector const NativeArchs = { _config->Find("APT::Architecture"), "implicit:all" }; bool const GzipIndex = _config->FindB("Acquire::GzipIndexes", false); for (std::vector::const_iterator E = entries.begin(); E != entries.end(); ++E) { @@ -210,15 +210,15 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI, Options.insert(std::make_pair("SITE", Site)); Options.insert(std::make_pair("RELEASE", Release)); if (tplMetaKey.find("$(COMPONENT)") != std::string::npos) - Options.insert(std::make_pair("COMPONENT", E->Name)); + Options.emplace("COMPONENT", E->Name); if (tplMetaKey.find("$(LANGUAGE)") != std::string::npos) - Options.insert(std::make_pair("LANGUAGE", *L)); + Options.emplace("LANGUAGE", *L); if (tplMetaKey.find("$(ARCHITECTURE)") != std::string::npos) - Options.insert(std::make_pair("ARCHITECTURE", *A)); + Options.emplace("ARCHITECTURE", (*A == "implicit:all") ? "all" : *A); else if (tplMetaKey.find("$(NATIVE_ARCHITECTURE)") != std::string::npos) - Options.insert(std::make_pair("ARCHITECTURE", NativeArch)); + Options.emplace("ARCHITECTURE", (NativeArch == "implicit:all") ? "all" : NativeArch); if (tplMetaKey.find("$(NATIVE_ARCHITECTURE)") != std::string::npos) - Options.insert(std::make_pair("NATIVE_ARCHITECTURE", NativeArch)); + Options.emplace("NATIVE_ARCHITECTURE", (NativeArch == "implicit:all") ? "all" : NativeArch); std::string MetaKey = tplMetaKey; std::string ShortDesc = tplShortDesc; @@ -299,11 +299,16 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI, Options.insert(std::make_pair("SOURCESENTRY", E->sourcesEntry)); bool IsOpt = IsOptional; - if (IsOpt == false) { auto const arch = Options.find("ARCHITECTURE"); if (arch != Options.end() && arch->second == "all") - IsOpt = true; + { + // one of them must be implicit:all then + if (*A != "all" && NativeArch != "all") + IsOpt = true; + else // user used arch=all explicitly + Options.emplace("Force-Support-For-All", "yes"); + } } IndexTarget Target( @@ -719,6 +724,10 @@ bool debReleaseIndex::IsArchitectureSupported(std::string const &arch) const/*{{ /*}}}*/ bool debReleaseIndex::IsArchitectureAllSupportedFor(IndexTarget const &target) const/*{{{*/ { + if (target.Options.find("Force-Support-For-All") != target.Options.end()) + return true; + if (IsArchitectureSupported("all") == false) + return false; if (d->NoSupportForAll.empty()) return true; return std::find(d->NoSupportForAll.begin(), d->NoSupportForAll.end(), target.Option(IndexTarget::CREATED_BY)) == d->NoSupportForAll.end(); @@ -856,39 +865,114 @@ pkgCache::RlsFileIterator debReleaseIndex::FindInCache(pkgCache &Cache, bool con } /*}}}*/ -static std::vector parsePlusMinusOptions(std::string const &Name, /*{{{*/ - std::map const &Options, std::vector const &defaultValues) +class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/ { - std::map::const_iterator val = Options.find(Name); - std::vector Values; - if (val != Options.end()) - Values = VectorizeString(val->second, ','); - else - Values = defaultValues; - - // all is a very special architecture users shouldn't be concerned with explicitly - if (Name == "arch" && std::find(Values.begin(), Values.end(), "all") == Values.end()) - Values.push_back("all"); - - if ((val = Options.find(Name + "+")) != Options.end()) + static std::vector getDefaultSetOf(std::string const &Name, + std::map const &Options, std::vector const &defaultValues) { - std::vector const plus = VectorizeString(val->second, ','); - std::copy_if(plus.begin(), plus.end(), std::back_inserter(Values), [&Values](std::string const &v) { - return std::find(Values.begin(), Values.end(), v) == Values.end(); - }); + auto const val = Options.find(Name); + if (val != Options.end()) + return VectorizeString(val->second, ','); + return defaultValues; } - if ((val = Options.find(Name + "-")) != Options.end()) + static std::vector applyPlusMinusOptions(std::string const &Name, + std::map const &Options, std::vector &&Values) { - std::vector const minus = VectorizeString(val->second, ','); - Values.erase(std::remove_if(Values.begin(), Values.end(), [&minus](std::string const &v) { - return std::find(minus.begin(), minus.end(), v) != minus.end(); - }), Values.end()); + auto val = Options.find(Name + "+"); + if (val != Options.end()) + { + std::vector const plus = VectorizeString(val->second, ','); + std::copy_if(plus.begin(), plus.end(), std::back_inserter(Values), [&Values](std::string const &v) { + return std::find(Values.begin(), Values.end(), v) == Values.end(); + }); + } + if ((val = Options.find(Name + "-")) != Options.end()) + { + std::vector const minus = VectorizeString(val->second, ','); + Values.erase(std::remove_if(Values.begin(), Values.end(), [&minus](std::string const &v) { + return std::find(minus.begin(), minus.end(), v) != minus.end(); + }), Values.end()); + } + return Values; } - return Values; -} - /*}}}*/ -class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/ -{ + static std::vector parsePlusMinusOptions(std::string const &Name, + std::map const &Options, std::vector const &defaultValues) + { + return applyPlusMinusOptions(Name, Options, getDefaultSetOf(Name, Options, defaultValues)); + } + static std::vector parsePlusMinusArchOptions(std::string const &Name, + std::map const &Options) + { + auto Values = getDefaultSetOf(Name, Options, APT::Configuration::getArchitectures()); + // all is a very special architecture users shouldn't be concerned with explicitly + // but if the user does, do not override the choice + auto const val = Options.find(Name + "-"); + if (val != Options.end()) + { + std::vector const minus = VectorizeString(val->second, ','); + if (std::find(minus.begin(), minus.end(), "all") != minus.end()) + return applyPlusMinusOptions(Name, Options, std::move(Values)); + } + Values = applyPlusMinusOptions(Name, Options, std::move(Values)); + if (std::find(Values.begin(), Values.end(), "all") == Values.end()) + Values.push_back("implicit:all"); + return Values; + } + static std::vector parsePlusMinusTargetOptions(char const * const Name, + std::map const &Options) + { + std::vector const alltargets = _config->FindVector(std::string("Acquire::IndexTargets::") + Name, "", true); + std::vector deftargets; + deftargets.reserve(alltargets.size()); + std::copy_if(alltargets.begin(), alltargets.end(), std::back_inserter(deftargets), [&](std::string const &t) { + std::string c = "Acquire::IndexTargets::"; + c.append(Name).append("::").append(t).append("::DefaultEnabled"); + return _config->FindB(c, true); + }); + std::vector mytargets = parsePlusMinusOptions("target", Options, deftargets); + for (auto const &target : alltargets) + { + std::map::const_iterator const opt = Options.find(target); + if (opt == Options.end()) + continue; + 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()); + } + return mytargets; + } + metaIndex::TriState GetTriStateOption(std::mapconst &Options, char const * const name) const { std::map::const_iterator const opt = Options.find(name); @@ -956,11 +1040,8 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/ return true; } - protected: - - bool CreateItemInternal(std::vector &List, std::string const &URI, - std::string const &Dist, std::string const &Section, - bool const &IsSrc, std::map const &Options) const + static debReleaseIndex * GetDebReleaseIndexBy(std::vector &List, std::string const &URI, + std::string const &Dist, std::map const &Options) { std::map ReleaseOptions = {{ { "BASE_URI", constructMetaIndexURI(URI, Dist, "") }, @@ -991,7 +1072,7 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/ if (URItoFileName(D->MetaIndexURI("Release")) == FileName) { if (MapsAreEqual(ReleaseOptions, D->GetReleaseOptions(), URI, Dist) == false) - return false; + return nullptr; Deb = D; break; } @@ -1003,56 +1084,16 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/ Deb = new debReleaseIndex(URI, Dist, ReleaseOptions); List.push_back(Deb); } + return Deb; + } - std::vector const alltargets = _config->FindVector(std::string("Acquire::IndexTargets::") + Name, "", true); - std::vector deftargets; - deftargets.reserve(alltargets.size()); - std::copy_if(alltargets.begin(), alltargets.end(), std::back_inserter(deftargets), [&](std::string const &t) { - std::string c = "Acquire::IndexTargets::"; - c.append(Name).append("::").append(t).append("::DefaultEnabled"); - return _config->FindB(c, true); - }); - std::vector mytargets = parsePlusMinusOptions("target", Options, deftargets); - for (auto const &target : alltargets) - { - std::map::const_iterator const opt = Options.find(target); - if (opt == Options.end()) - continue; - 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()); - } + protected: + + bool CreateItemInternal(std::vector &List, std::string const &URI, + std::string const &Dist, std::string const &Section, + bool const &IsSrc, std::map const &Options) const + { + auto const Deb = GetDebReleaseIndexBy(List, URI, Dist, Options); bool const UsePDiffs = GetBoolOption(Options, "pdiffs", _config->FindB("Acquire::PDiffs", true)); @@ -1072,8 +1113,8 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/ entry->second, IsSrc, Section, - mytargets, - parsePlusMinusOptions("arch", Options, APT::Configuration::getArchitectures()), + parsePlusMinusTargetOptions(Name, Options), + parsePlusMinusArchOptions("arch", Options), parsePlusMinusOptions("lang", Options, APT::Configuration::getLanguages(true)), UsePDiffs, UseByHash