From 70c669e2566d119559d2986635bb6c1d0d368073 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 4 Sep 2021 16:10:50 +0200 Subject: Streamline access to barbarian architecture functionality APT is not the place this information should be stored at, but it is a good place to experiment and see what will be (not) needed in the future for a proper implementation higher up the stack. This is why "BarbarianArchitectures" is chosen instead of a more neutral and/or sensible "VeryForeign" and isn't readily exported in the API to other clients for this PoC as a to be drawn up standard will likely require potentially incompatible changes. Having a then outdated and slightly different implementation block a "good" name would be bad. The functionality itself mostly exists (ignoring bugs) since the introduction of MultiArch as we always had the risk of encountering packages of architectures not known to dpkg (forced onto the system, potentially before MultiArch) we had to deal with somehow and other edge cases. All this commit really does is allowing what could previously only be achieved with editing sources.list and some conf options via a single config option: -o APT::BarbarianArchitectures=foo,bar --- apt-pkg/aptconfiguration.cc | 22 +++++++++------------- apt-pkg/deb/debmetaindex.cc | 20 +++++++++++++++----- apt-pkg/edsp.cc | 7 ++++++- 3 files changed, 30 insertions(+), 19 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 671c3d553..00a97a0e7 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -315,13 +315,11 @@ bool Configuration::checkLanguage(std::string Lang, bool const All) { /*}}}*/ // getArchitectures - Return Vector of preferred Architectures /*{{{*/ std::vector const Configuration::getArchitectures(bool const &Cached) { - using std::string; - - std::vector static archs; + std::vector static archs; if (likely(Cached == true) && archs.empty() == false) return archs; - string const arch = _config->Find("APT::Architecture"); + std::string const arch = _config->Find("APT::Architecture"); archs = _config->FindVector("APT::Architectures"); if (archs.empty() == true && _system != nullptr) @@ -331,15 +329,13 @@ std::vector const Configuration::getArchitectures(bool const &Cache std::find(archs.begin(), archs.end(), arch) == archs.end()) archs.insert(archs.begin(), arch); - // erase duplicates and empty strings - for (std::vector::reverse_iterator a = archs.rbegin(); - a != archs.rend(); ++a) { - if (a->empty() == true || std::find(a + 1, archs.rend(), *a) != archs.rend()) - archs.erase(a.base()-1); - if (a == archs.rend()) - break; - } - + // erase duplicates, empty strings and very foreign architectures + auto newend = std::remove_if(archs.begin(), archs.end(), [](auto const &a) { return a.empty(); }); + for (auto a = archs.begin(); a != newend; ++a) + newend = std::remove(std::next(a), newend, *a); + for (auto const &f : _config->FindVector("APT::BarbarianArchitectures")) + newend = std::remove(archs.begin(), newend, f); + archs.erase(newend, archs.end()); return archs; } /*}}}*/ diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index f24a5e79e..d78cea758 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -966,13 +967,13 @@ pkgCache::RlsFileIterator debReleaseIndex::FindInCache(pkgCache &Cache, bool con class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/ { - static std::vector getDefaultSetOf(std::string const &Name, - std::map const &Options, std::vector const &defaultValues) + static std::optional> getDefaultSetOf(std::string const &Name, + std::map const &Options) { auto const val = Options.find(Name); if (val != Options.end()) return VectorizeString(val->second, ','); - return defaultValues; + return {}; } static std::vector applyPlusMinusOptions(std::string const &Name, std::map const &Options, std::vector &&Values) @@ -997,12 +998,21 @@ 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)); + return applyPlusMinusOptions(Name, Options, getDefaultSetOf(Name, Options).value_or(defaultValues)); } static std::vector parsePlusMinusArchOptions(std::string const &Name, std::map const &Options) { - auto Values = getDefaultSetOf(Name, Options, APT::Configuration::getArchitectures()); + std::vector Values; + if (auto opt = getDefaultSetOf(Name, Options); opt.has_value()) + Values = opt.value(); + else + { + Values = APT::Configuration::getArchitectures(); + auto veryforeign = _config->FindVector("APT::BarbarianArchitectures"); + Values.reserve(Values.size() + veryforeign.size()); + std::move(veryforeign.begin(), veryforeign.end(), std::back_inserter(Values)); + } // 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 + "-"); diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index 5bf23044b..b7c0d28d2 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -208,7 +208,10 @@ static bool WriteScenarioLimitedDependency(FileFd &output, /*}}}*/ static bool checkKnownArchitecture(std::string const &arch) /*{{{*/ { - return APT::Configuration::checkArchitecture(arch); + if (APT::Configuration::checkArchitecture(arch)) + return true; + static auto const veryforeign = _config->FindVector("APT::BarbarianArchitectures"); + return std::find(veryforeign.begin(), veryforeign.end(), arch) != veryforeign.end(); } /*}}}*/ static bool WriteGenericRequestHeaders(FileFd &output, APT::StringView const head)/*{{{*/ @@ -217,6 +220,8 @@ static bool WriteGenericRequestHeaders(FileFd &output, APT::StringView const hea "Architectures:"); for (auto const &a : APT::Configuration::getArchitectures()) WriteOkay(Okay, output, " ", a); + for (auto const &a : _config->FindVector("APT::BarbarianArchitectures")) + WriteOkay(Okay, output, " ", a); return WriteOkay(Okay, output, "\n"); } /*}}}*/ -- cgit v1.2.3-70-g09d2