Просмотр исходного кода

implement arch+= and arch-= for sources.list

Default is to acquire all architectures from APT::Architectures which
can be changed by arch=, but this isn't very flexible if you want
"mostly" the default as you have to hardcode the architectures then,
so arch-= and arch+= can be used to add/remove architectures from the
default set.

On a machine with 'amd64' and 'i386' configured the lines:
 deb [arch+=armel] http://example.org/debian wheezy rocks
 deb [arch-=amd64] http://example.org/debian jessie rocks
will result in the download of:
 wheezy Packages for 'amd64', 'i386' and 'armel'
 jessie Packages for 'i386'
David Kalnischkies лет назад: 13
Родитель
Сommit
3d1be93dc4

+ 21 - 2
apt-pkg/deb/debmetaindex.cc

@@ -373,10 +373,29 @@ class debSLTypeDebian : public pkgSourceList::Type
 			   string const &Dist, string const &Section,
 			   bool const &IsSrc, map<string, string> const &Options) const
    {
-      map<string, string>::const_iterator const arch = Options.find("arch");
-      vector<string> const Archs =
+      // parse arch=, arch+= and arch-= settings
+      map<string, string>::const_iterator arch = Options.find("arch");
+      vector<string> Archs =
 		(arch != Options.end()) ? VectorizeString(arch->second, ',') :
 				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 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);
+	 }
+      }
+
       map<string, string>::const_iterator const trusted = Options.find("trusted");
 
       for (vector<metaIndex *>::const_iterator I = List.begin();

+ 5 - 1
doc/sources.list.5.xml

@@ -114,10 +114,14 @@
    <literal><replaceable>setting</replaceable>=<replaceable>value</replaceable></literal>.
    Multiple settings are separated by spaces. The following settings are supported by APT
    (note however that unsupported settings will be ignored silently):
-   <itemizedlist><listitem><para><literal>arch=<replaceable>arch1</replaceable>,<replaceable>arch2</replaceable>,…</literal>
+   <itemizedlist>
+   <listitem><para><literal>arch=<replaceable>arch1</replaceable>,<replaceable>arch2</replaceable>,…</literal>
    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>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;

+ 85 - 0
test/integration/test-sourceslist-arch-plusminus-options

@@ -0,0 +1,85 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'amd64'
+
+testbinaries() {
+	msgtest 'Test acquired archs for' "$1"
+	shift
+	rm -f gotarchs.list
+	aptget update --print-uris | grep -o '/binary-[a-z0-9-]\+/Packages' | sort > gotarchs.list
+	while [ -n "$1" ]; do
+		echo "/binary-${1}/Packages"
+		shift
+	done | sort | checkdiff - gotarchs.list && msgpass || msgfail
+}
+
+echo 'deb http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'default & native' 'amd64'
+configarchitecture 'amd64' 'i386'
+testbinaries 'default & native + foreign' 'amd64' 'i386'
+configarchitecture 'amd64' 'i386' 'armel' 'armhf' 'mips' 'mipsel'
+testbinaries 'default & native + many foreigns' 'amd64' 'i386' 'armel' 'armhf' 'mips' 'mipsel'
+
+echo 'deb [arch=amd64] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch=native' 'amd64'
+
+echo 'deb [arch=mips] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch=foreign' 'mips'
+
+echo 'deb [arch=kfreebsd-armel] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch=unknown' 'kfreebsd-armel'
+
+echo 'deb [arch=amd64,i386] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch=native,foreign' 'amd64' 'i386'
+
+echo 'deb [arch=mips,armhf] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch=foreign,foreign' 'mips' 'armhf'
+
+echo 'deb [arch=kfreebsd-armel,hurd-powerpc,mipsel,armel] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch=unknown,unknown,foreign,foreign' 'kfreebsd-armel' 'hurd-powerpc' 'mipsel' 'armel'
+
+echo 'deb [arch+=amd64] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch+=native' 'amd64' 'i386' 'armel' 'armhf' 'mips' 'mipsel'
+
+echo 'deb [arch+=mips] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch+=foreign' 'amd64' 'i386' 'armel' 'armhf' 'mips' 'mipsel'
+
+echo 'deb [arch+=mips,armhf,i386] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch+=foreign,foreign,foreign' 'amd64' 'i386' 'armel' 'armhf' 'mips' 'mipsel'
+
+echo 'deb [arch+=hurd-powerpc] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch+=unknown' 'amd64' 'i386' 'armel' 'armhf' 'mips' 'mipsel' 'hurd-powerpc'
+
+echo 'deb [arch+=mips,hurd-powerpc,i386] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch+=foreign,unknown,foreign' 'amd64' 'i386' 'armel' 'armhf' 'mips' 'mipsel' 'hurd-powerpc'
+
+echo 'deb [arch-=amd64] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch-=native' 'i386' 'armel' 'armhf' 'mips' 'mipsel'
+
+echo 'deb [arch-=mips] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch-=foreign' 'amd64' 'i386' 'armel' 'armhf' 'mipsel'
+
+echo 'deb [arch-=mips,armhf,i386] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch-=foreign,foreign,foreign' 'amd64' 'armel' 'mipsel'
+
+echo 'deb [arch-=hurd-powerpc] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch-=unknown' 'amd64' 'i386' 'armel' 'armhf' 'mips' 'mipsel'
+
+echo 'deb [arch-=mips,hurd-powerpc,i386] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'arch-=foreign,unknown,foreign' 'amd64' 'armel' 'armhf' 'mipsel'
+
+echo 'deb [arch=mips,i386 arch-=mips] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'substract from a arch-set' 'i386'
+
+echo 'deb [arch=mips,i386 arch-=mips] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'useless substract from a arch-set' 'i386'
+
+echo 'deb [arch=mips,i386 arch+=armhf] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'addition to a arch-set' 'i386' 'mips' 'armhf'
+
+echo 'deb [arch=mips,i386 arch+=mips] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testbinaries 'useless addition to a arch-set' 'i386' 'mips'