Browse Source

implement Identifier field for IndexTargets

A frontend like apt-file is only interested in a specific set of files
and selects those easily via "Created-By". If it supports two locations
for those files through it would need to select both and a user would
need to know that implementation detail for sources.list configuration.

The "Identifier" field is hence introduced which by default has the same
value as "Created-By", but can be freely configured – especially it can
be used to give two indexes the same identifier.
David Kalnischkies 8 years ago
parent
commit
39c724b484

+ 22 - 9
apt-pkg/deb/debmetaindex.cc

@@ -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);
@@ -229,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<std::string, std::string>::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);
 		  }
 
 		  {
@@ -291,6 +295,7 @@ 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));
@@ -945,12 +950,13 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type		/*{{{*/
 	 std::map<std::string, std::string>::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)
@@ -972,6 +978,13 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type		/*{{{*/
 	 if (Changed == false)
 	    break;
       }
+      // remove duplicates without changing the order (in first appearance)
+      {
+	 std::set<std::string> 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);
       {

+ 1 - 0
apt-pkg/indexfile.cc

@@ -137,6 +137,7 @@ std::string IndexTarget::Option(OptionKeys const EnumKey) const		/*{{{*/
       APT_CASE(ARCHITECTURE);
       APT_CASE(BASE_URI);
       APT_CASE(REPO_URI);
+      APT_CASE(IDENTIFIER);
       APT_CASE(TARGET_OF);
       APT_CASE(CREATED_BY);
       APT_CASE(FALLBACK_OF);

+ 1 - 0
apt-pkg/indexfile.h

@@ -92,6 +92,7 @@ class IndexTarget							/*{{{*/
       BY_HASH,
       KEEPCOMPRESSEDAS,
       FALLBACK_OF,
+      IDENTIFIER,
    };
    std::string Option(OptionKeys const Key) const;
    bool OptionBool(OptionKeys const Key) const;

+ 1 - 0
debian/apt-doc.docs

@@ -1,2 +1,3 @@
 README.progress-reporting
 doc/external-dependency-solver-protocol.txt
+doc/acquire-additional-files.txt

+ 15 - 5
doc/acquire-additional-files.txt

@@ -46,10 +46,11 @@ multiple types!
 
 After the type you can pick any valid and unique string which preferable
 refers to the file it downloads (In the example we picked 'Packages').
-This string is used as identifier for the target class and accessible as
-'Created-By' e.g. in the "apt-get indextargets" output as detailed
-below.  It is also used to allow user to enable/disable targets per
-sources.list entry.
+This string is used as identifier (if not explicitly set otherwise) for
+the target class and accessible as 'Identifier' and 'Created-By' e.g.
+in the "apt-get indextargets" output as detailed below. The identifier
+is also used to allow user to enable/disable targets per sources.list
+entry.
 
 All targets have three main properties you can define:
 * MetaKey: The identifier of the file to be downloaded as used in the
@@ -71,6 +72,12 @@ All targets have three main properties you can define:
 
 
 Additional optional properties:
+* Identifier: The default value is the unique string identifying this
+  file (in the example above it was 'Packages') also accessible as
+  Created-By. The difference is that using this property multiple files
+  can be subsumed under one identifier e.g. if you configure multiple
+  possible locations for the files (with Fallback-Of), but the front-end
+  doesn't need to handle files from the different locations differently.
 * DefaultEnabled: The default value is 'yes' which means that apt will
   try to acquire this target from all sources. If set to 'no' the user
   has to explicitly enable this target in the sources.list file with the
@@ -207,7 +214,7 @@ own output style. The variables are what you see in the output, just all
 uppercase and wrapped in $(), as in the configuration file.
 
 To get all the filenames of all Translation-en files you can e.g. call:
-	apt-get indextargets --format '$(FILENAME)' "Created-By: Translations" "Language: en"
+	apt-get indextargets --format '$(FILENAME)' "Identifier: Translations" "Language: en"
 
 The line-based filtering and the formatting is rather crude and feature-
 less by design: The default format is Debians standard format deb822 (in
@@ -246,6 +253,9 @@ Remarks on fields only available in (default) --release-info mode:
 Remarks on other available fields:
 * MetaKey, ShortDesc, Description, Site, Release: as defined
   by the configuration and described further above.
+* Identifier: Defaults to the value of Created-By, but can be set
+  explicitly in the configuration (see above). Prefer this field over
+  Created-By to subsume multiple file(location)s (see Fallback-Of).
 * Created-By: configuration entity responsible for this target
 * Target-Of: type of the sources.list entry
 * URI, Repo-URI: avoid using. Contains potentially username/password.

+ 2 - 2
doc/apt-get.8.xml

@@ -249,8 +249,8 @@
 	      working with APT to get information as well as filenames for
 	      downloaded files so they can use them as well instead of
 	      downloading them again on their own. Detailed documentation is
-	      omitted here and can instead be found in the source tree in
-	      <literal><filename>doc/acquire-additional-files.txt</filename></literal>.
+	      omitted here and can instead be found in the file
+	      &apt-acquire-additional-files; shipped by the <package>apt-doc</package> package.
 	   </para>
 	</listitem>
      </varlistentry>

+ 2 - 0
doc/apt-verbatim.ent

@@ -196,6 +196,8 @@
   </citerefentry>"
 >
 
+<!ENTITY apt-acquire-additional-files "<literal><filename>/usr/share/doc/apt-doc/acquire-additional-files.txt</filename></literal>">
+
 <!-- Boiler plate docinfo section -->
 <!ENTITY apt-email "
    <address>

+ 7 - 6
doc/sources.list.5.xml

@@ -222,10 +222,12 @@ deb-src [ option1=value1 option2=value2 ] uri suite [component1] [component2] [.
 		(<option>target</option>) is a multivalue option defining
 		which download targets apt will try to acquire from this
 		source. If not specified, the default set is defined by the
-		<option>Acquire::IndexTargets</option> configuration scope.
-		Additionally, specific targets can be enabled or disabled by
-		using the identifier as field name instead of using this
-		multivalue option.
+		<option>Acquire::IndexTargets</option> configuration scope
+		(targets are specified by their name in the
+		<literal>Created-By</literal> field).
+		Additionally, targets can be enabled or disabled by using the
+		<literal>Identifier</literal> field as an option with a boolean
+		value instead of using this multivalue option.
 	  </para></listitem>
 
 	  <listitem><para><option>PDiffs</option> (<option>pdiffs</option>)
@@ -501,8 +503,7 @@ Components: main contrib
  </refsect1>
 
  <refsect1><title>See Also</title>
-   <para>&apt-get;, &apt-conf;
-   </para>
+   <para>&apt-get;, &apt-conf;, &apt-acquire-additional-files;</para>
  </refsect1>
 
  &manbugs;

+ 17 - 19
test/integration/test-apt-acquire-additional-files

@@ -51,15 +51,15 @@ readfile() {
 	done
 }
 
-testequal "$(readfile Contents-amd64 Contents-all)" aptget indextargets --no-release-info --format '$(FILENAME)' 'Created-By: Contents'
-testempty aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
+testequal "$(readfile Contents-amd64 Contents-all)" aptget indextargets --no-release-info --format '$(FILENAME)' 'Identifier: Contents'
+testempty aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 # lets fake the existence of a compressed Contents file
 touch "./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64.gz"
 chmod 644 "./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64.gz"
-testequal "$(readfile Contents-amd64.gz)" aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
+testequal "$(readfile Contents-amd64.gz)" aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 touch "./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all.gz"
 chmod 644 "./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all.gz"
-testequal "$(readfile Contents-amd64.gz Contents-all.gz)" aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
+testequal "$(readfile Contents-amd64.gz Contents-all.gz)" aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 
 testequal "'http://localhost:${APTHTTPPORT}/dists/unstable/InRelease' localhost:${APTHTTPPORT}_dists_unstable_InRelease 0 
 'http://localhost:${APTHTTPPORT}/dists/unstable/main/source/Sources.xz' localhost:${APTHTTPPORT}_dists_unstable_main_source_Sources 0 
@@ -72,7 +72,7 @@ testequal "'http://localhost:${APTHTTPPORT}/dists/unstable/InRelease' localhost:
 # apt believes the Contents files we faked are good
 testsuccessequal "Hit:1 http://localhost:${APTHTTPPORT} unstable InRelease
 Reading package lists..." aptget update
-testequal "$(readfile Contents-amd64.gz Contents-all.gz)" aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
+testequal "$(readfile Contents-amd64.gz Contents-all.gz)" aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 
 find rootdir/var/lib/apt/lists -name '*Contents*' -delete
 
@@ -91,13 +91,13 @@ Reading package lists..." aptget update
 
 testequal "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64" find rootdir/var/lib/apt/lists -name '*Contents-amd64*'
 testequal "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all" find rootdir/var/lib/apt/lists -name '*Contents-all*'
-testequal "$(readfile Contents-amd64 Contents-all)" aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
+testequal "$(readfile Contents-amd64 Contents-all)" aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 testsuccess cmp "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64" 'aptarchive/dists/unstable/main/Contents-amd64'
 testsuccess cmp "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all" 'aptarchive/dists/unstable/main/Contents-all'
 
 rm ./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64 \
 	./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all
-testempty aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
+testempty aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 
 # if we asked for keeping it compressed, keep it
 msgmsg "Normal Contents file with KeepCompressed"
@@ -109,13 +109,13 @@ Reading package lists..." aptget update
 
 testequal "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64.$LOWCOSTEXT" find rootdir/var/lib/apt/lists -name '*Contents-amd64*'
 testequal "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all.$LOWCOSTEXT" find rootdir/var/lib/apt/lists -name '*Contents-all*'
-testequal "$(readfile Contents-amd64.$LOWCOSTEXT Contents-all.$LOWCOSTEXT)" aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
+testequal "$(readfile Contents-amd64.$LOWCOSTEXT Contents-all.$LOWCOSTEXT)" aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 testequal "$(apthelper cat-file rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64.$LOWCOSTEXT)" apthelper cat-file 'aptarchive/dists/unstable/main/Contents-amd64.gz'
 testequal "$(apthelper cat-file rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all.$LOWCOSTEXT)" apthelper cat-file 'aptarchive/dists/unstable/main/Contents-all.gz'
 
 rm ./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64.$LOWCOSTEXT
 rm ./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all.$LOWCOSTEXT
-testempty aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
+testempty aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 
 msgmsg "Compressed Contents file"
 # and no automatic uncompress based on the name please,
@@ -145,7 +145,7 @@ Reading package lists..." aptget update
 
 	testequal "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64.gz" find rootdir/var/lib/apt/lists -name '*Contents-amd64*'
 	testequal "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all.gz" find rootdir/var/lib/apt/lists -name '*Contents-all*'
-	testequal "$(readfile Contents-amd64.gz Contents-all.gz)" aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
+	testequal "$(readfile Contents-amd64.gz Contents-all.gz)" aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 	testsuccess cmp "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64.gz" 'aptarchive/dists/unstable/main/Contents-amd64.gz'
 	testsuccess cmp "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all.gz" 'aptarchive/dists/unstable/main/Contents-all.gz'
 }
@@ -155,19 +155,20 @@ msgmsg "Compressed Contents file from native architecture"
 echo 'Acquire::IndexTargets::deb::Contents::MetaKey "$(COMPONENT)/Contents-$(NATIVE_ARCHITECTURE).gz";' >> rootdir/etc/apt/apt.conf.d/content-target.conf
 rm ./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64.gz
 rm ./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all.gz
-testempty aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
+testempty aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 runthistest
 
 msgmsg "Contents with 3 MetaKeys, first match"
 rm ./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64.gz
 rm ./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all.gz
-testempty aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
+testempty aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 cat > rootdir/etc/apt/apt.conf.d/content-target.conf <<EOF
 Acquire::IndexTargets::deb::Contents3 {
 	MetaKey "main/Contents-all";
 	ShortDescription "Contents3";
 	Description "\$(RELEASE) all Contents3";
 	Fallback-Of "Contents2";
+	Identifier "Contents";
 };
 Acquire::IndexTargets::deb::Contents {
 	MetaKey "\$(COMPONENT)/Contents-amd64";
@@ -179,6 +180,7 @@ Acquire::IndexTargets::deb::Contents2 {
 	ShortDescription "Contents2";
 	Description "\$(RELEASE) all Contents2";
 	Fallback-Of "Contents";
+	Identifier "Contents";
 };
 EOF
 testequal "'http://localhost:${APTHTTPPORT}/dists/unstable/InRelease' localhost:${APTHTTPPORT}_dists_unstable_InRelease 0 
@@ -191,14 +193,12 @@ testsuccessequal "Hit:1 http://localhost:${APTHTTPPORT} unstable InRelease
 Get:2 http://localhost:${APTHTTPPORT} unstable/main amd64 Contents [$(stat -c%s aptarchive/dists/unstable/main/Contents-amd64.gz) B]
 Reading package lists..." aptget update
 testequal "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64" find rootdir/var/lib/apt/lists -name '*Contents*'
-testequal "$(readfile Contents-amd64)" aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
-testempty aptget indextargets --format '$(FILENAME)' 'Created-By: Contents2'
-testempty aptget indextargets --format '$(FILENAME)' 'Created-By: Contents3'
+testequal "$(readfile Contents-amd64)" aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 testsuccess cmp "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64" 'aptarchive/dists/unstable/main/Contents-amd64'
 
 msgmsg "Contents with 3 MetaKeys, third match"
 rm ./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-amd64
-testempty aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
+testempty aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 echo 'Acquire::IndexTargets::deb::Contents::MetaKey "$(COMPONENT)/Contents-i386";' >> rootdir/etc/apt/apt.conf.d/content-target.conf
 testequal "'http://localhost:${APTHTTPPORT}/dists/unstable/InRelease' localhost:${APTHTTPPORT}_dists_unstable_InRelease 0 
 'http://localhost:${APTHTTPPORT}/dists/unstable/main/source/Sources.xz' localhost:${APTHTTPPORT}_dists_unstable_main_source_Sources 0 
@@ -210,9 +210,7 @@ testsuccessequal "Hit:1 http://localhost:${APTHTTPPORT} unstable InRelease
 Get:2 http://localhost:${APTHTTPPORT} unstable all Contents3 [$(stat -c%s aptarchive/dists/unstable/main/Contents-all.gz) B]
 Reading package lists..." aptget update
 testequal "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all" find rootdir/var/lib/apt/lists -name '*Contents*'
-testequal "$(readfile Contents-all)" aptget indextargets --format '$(FILENAME)' 'Created-By: Contents3'
-testempty aptget indextargets --format '$(FILENAME)' 'Created-By: Contents'
-testempty aptget indextargets --format '$(FILENAME)' 'Created-By: Contents2'
+testequal "$(readfile Contents-all)" aptget indextargets --format '$(FILENAME)' 'Identifier: Contents'
 testsuccess cmp "rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all" 'aptarchive/dists/unstable/main/Contents-all'
 
 rm ./rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_unstable_main_Contents-all

+ 2 - 2
test/integration/test-sourceslist-lang-plusminus-options

@@ -11,7 +11,7 @@ testlangs() {
 	local LANGS="$2"
 	shift 2
 	rm -f gotlangs.list
-	aptget indextargets --no-release-info 'Created-By: Translations' "$@" --format '$(LANGUAGE)' | sort -u > gotlangs.list
+	aptget indextargets --no-release-info 'Identifier: Translations' "$@" --format '$(LANGUAGE)' | sort -u > gotlangs.list
 	if [ -z "$LANGS" ]; then
 		echo -n | tr ',' '\n' | sort | checkdiff - gotlangs.list && msgpass || msgfail
 	else
@@ -45,7 +45,7 @@ testlangs 'lang=de_DE' 'de_DE'
 echo 'deb [lang=none] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
 testlangs 'lang=none' ''
 testequal 'amd64
-all' aptget indextargets --no-release-info 'Created-By: Packages' --format '$(ARCHITECTURE)'
+all' aptget indextargets --no-release-info 'Identifier: Packages' --format '$(ARCHITECTURE)'
 
 echo 'deb [lang+=pt] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
 testlangs 'lang+=pt' 'en,de,de_DE,pt'

+ 31 - 19
test/integration/test-sourceslist-target-plusminus-options

@@ -27,10 +27,17 @@ Acquire::IndexTargets::deb::Contents {
 	ShortDescription "Contents";
 	Description "\$(RELEASE)/\$(COMPONENT) \$(ARCHITECTURE) Contents";
 };
+Acquire::IndexTargets::deb::Contents2 {
+	MetaKey "Contents-\$(ARCHITECTURE)";
+	ShortDescription "Contents2";
+	Description "\$(RELEASE) \$(ARCHITECTURE) Contents2";
+	Fallback-Of "Contents";
+	Identifier "Contents";
+};
 EOF
 
 echo 'deb http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'default + Contents' 'Packages' 'Translations' 'Contents'
+testtargets 'default + Contents' 'Packages' 'Translations' 'Contents' 'Contents2'
 
 echo 'deb [target=Packages] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
 testtargets 'force Packages target' 'Packages'
@@ -42,38 +49,40 @@ echo 'deb [target=Translations,Contents] http://example.org/debian stable rocks'
 testtargets 'force two targets' 'Contents' 'Translations'
 
 echo 'deb [target+=Translations,Contents] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'add existing' 'Packages' 'Contents' 'Translations'
+testtargets 'add existing' 'Packages' 'Contents' 'Translations' 'Contents2'
 
 echo 'deb [target+=AppStream] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'add non-existing' 'Packages' 'Contents' 'Translations'
+testtargets 'add non-existing' 'Packages' 'Contents' 'Translations' 'Contents2'
 
 echo 'deb [target-=Translations,Contents] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'remove existing' 'Packages'
+testtargets 'remove existing' 'Packages' 'Contents2'
 
 echo 'deb [target-=AppStream] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'remove non-existing' 'Packages' 'Contents' 'Translations'
+testtargets 'remove non-existing' 'Packages' 'Contents' 'Translations' 'Contents2'
 
 echo 'deb [AppStream=yes] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'activate non-existing' 'Packages' 'Contents' 'Translations'
+testtargets 'activate non-existing' 'Packages' 'Contents' 'Translations' 'Contents2'
 
 echo 'deb [AppStream=no] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'deactivate non-existing' 'Packages' 'Contents' 'Translations'
+testtargets 'deactivate non-existing' 'Packages' 'Contents' 'Translations' 'Contents2'
 
 echo 'deb [Contents=yes] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'activate existing' 'Packages' 'Contents' 'Translations'
+testtargets 'activate existing' 'Packages' 'Contents' 'Contents2' 'Translations'
 
 echo 'deb [Contents=no] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
 testtargets 'deactivate existing' 'Packages' 'Translations'
 
 echo 'deb [target=Packages Contents=yes] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'explicit + activate' 'Packages' 'Contents'
+testtargets 'explicit + activate' 'Packages' 'Contents' 'Contents2'
 
+echo 'deb [Contents=yes,target+=Contents] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testtargets 'duplications are okay' 'Packages' 'Translations' 'Contents' 'Contents2'
 
-msgmsg 'Contents NOT as a default target'
+msgmsg 'Contents NOT as a default target (but Contents2)'
 echo 'Acquire::IndexTargets::deb::Contents::DefaultEnabled "no";' > rootdir/etc/apt/apt.conf.d/content-target-notdefault.conf
 
 echo 'deb http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'default + Contents' 'Packages' 'Translations'
+testtargets 'default + Contents' 'Packages' 'Translations' 'Contents2'
 
 echo 'deb [target=Packages] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
 testtargets 'force Packages target' 'Packages'
@@ -85,28 +94,31 @@ echo 'deb [target=Translations,Contents] http://example.org/debian stable rocks'
 testtargets 'force two targets' 'Contents' 'Translations'
 
 echo 'deb [target+=Translations,Contents] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'add existing' 'Packages' 'Contents' 'Translations'
+testtargets 'add existing' 'Packages' 'Contents' 'Translations' 'Contents2'
 
 echo 'deb [target+=AppStream] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'add non-existing' 'Packages' 'Translations'
+testtargets 'add non-existing' 'Packages' 'Translations' 'Contents2'
 
 echo 'deb [target-=Translations,Contents] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'remove existing' 'Packages'
+testtargets 'remove existing' 'Packages' 'Contents2'
 
 echo 'deb [target-=AppStream] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'remove non-existing' 'Packages' 'Translations'
+testtargets 'remove non-existing' 'Packages' 'Translations' 'Contents2'
 
 echo 'deb [AppStream=yes] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'activate non-existing' 'Packages' 'Translations'
+testtargets 'activate non-existing' 'Packages' 'Translations' 'Contents2'
 
 echo 'deb [AppStream=no] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'deactivate non-existing' 'Packages' 'Translations'
+testtargets 'deactivate non-existing' 'Packages' 'Translations' 'Contents2'
 
 echo 'deb [Contents=yes] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'activate existing' 'Packages' 'Contents' 'Translations'
+testtargets 'activate existing' 'Packages' 'Contents' 'Contents2' 'Translations'
 
 echo 'deb [Contents=no] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
 testtargets 'deactivate existing' 'Packages' 'Translations'
 
 echo 'deb [target=Packages Contents=yes] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
-testtargets 'explicit + activate' 'Packages' 'Contents'
+testtargets 'explicit + activate' 'Packages' 'Contents' 'Contents2'
+
+echo 'deb [Contents=yes,target+=Contents] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list
+testtargets 'duplications are okay' 'Packages' 'Translations' 'Contents' 'Contents2'