Przeglądaj źródła

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 lat temu
rodzic
commit
3d1be93dc4

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

@@ -373,10 +373,29 @@ class debSLTypeDebian : public pkgSourceList::Type
 			   string const &Dist, string const &Section,
 			   string const &Dist, string const &Section,
 			   bool const &IsSrc, map<string, string> const &Options) const
 			   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, ',') :
 		(arch != Options.end()) ? VectorizeString(arch->second, ',') :
 				APT::Configuration::getArchitectures();
 				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");
       map<string, string>::const_iterator const trusted = Options.find("trusted");
 
 
       for (vector<metaIndex *>::const_iterator I = List.begin();
       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>.
    <literal><replaceable>setting</replaceable>=<replaceable>value</replaceable></literal>.
    Multiple settings are separated by spaces. The following settings are supported by APT
    Multiple settings are separated by spaces. The following settings are supported by APT
    (note however that unsupported settings will be ignored silently):
    (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
    can be used to specify for which architectures information should
    be downloaded. If this option is not set all architectures defined by the
    be downloaded. If this option is not set all architectures defined by the
    <literal>APT::Architectures</literal> option will be downloaded.</para></listitem>
    <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
    <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
    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;
    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'