summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2015-10-16 18:03:52 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2015-11-04 18:04:02 +0100
commitc3ded84c6f99bda4caf63c8662416ffb0189d31b (patch)
tree0b9c03d3ba4d44501091f13122e06d9d9cc6ad20
parent73fe49f9b4748eddb5a2dad4f0abb51a8f63564c (diff)
add binary-specific options via Binary scope
Especially with apt now, it can be useful to set an option only for apt and not for apt-get. Using a binary-specific subtree which is merged into the root seems like a simple enough trick to achieve this.
-rw-r--r--apt-pkg/contrib/configuration.cc53
-rw-r--r--apt-pkg/contrib/configuration.h2
-rw-r--r--apt-private/private-cmndline.cc18
-rw-r--r--doc/apt.conf.5.xml20
-rwxr-xr-xtest/integration/test-apt-showlist-orgroup-in-recommends42
-rw-r--r--test/libapt/configuration_test.cc17
6 files changed, 150 insertions, 2 deletions
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index 203de158b..d4bb72a8b 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -485,6 +485,59 @@ void Configuration::Clear(string const &Name)
}
}
/*}}}*/
+void Configuration::MoveSubTree(char const * const OldRootName, char const * const NewRootName)/*{{{*/
+{
+ // prevent NewRoot being a subtree of OldRoot
+ if (OldRootName == nullptr)
+ return;
+ if (NewRootName != nullptr)
+ {
+ if (strcmp(OldRootName, NewRootName) == 0)
+ return;
+ std::string const oldroot = std::string(OldRootName) + "::";
+ if (strcasestr(NewRootName, oldroot.c_str()) != NULL)
+ return;
+ }
+
+ Item * Top;
+ Item const * const OldRoot = Top = Lookup(OldRootName, false);
+ if (Top == nullptr)
+ return;
+ std::string NewRoot;
+ if (NewRootName != nullptr)
+ NewRoot.append(NewRootName).append("::");
+
+ Top->Value.clear();
+ Item * const Stop = Top;
+ Top = Top->Child;
+ Stop->Child = 0;
+ for (; Top != 0;)
+ {
+ if (Top->Child != 0)
+ {
+ Top = Top->Child;
+ continue;
+ }
+
+ while (Top != 0 && Top->Next == 0)
+ {
+ Set(NewRoot + Top->FullTag(OldRoot), Top->Value);
+ Item const * const Tmp = Top;
+ Top = Top->Parent;
+ delete Tmp;
+
+ if (Top == Stop)
+ return;
+ }
+
+ Set(NewRoot + Top->FullTag(OldRoot), Top->Value);
+ Item const * const Tmp = Top;
+ if (Top != 0)
+ Top = Top->Next;
+ delete Tmp;
+ }
+}
+ /*}}}*/
// Configuration::Exists - Returns true if the Name exists /*{{{*/
// ---------------------------------------------------------------------
/* */
diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h
index eacc26fda..97a01e4cf 100644
--- a/apt-pkg/contrib/configuration.h
+++ b/apt-pkg/contrib/configuration.h
@@ -103,6 +103,8 @@ class Configuration
bool Exists(const char *Name) const;
bool ExistsAny(const char *Name) const;
+ void MoveSubTree(char const * const OldRoot, char const * const NewRoot);
+
// clear a whole tree
void Clear(const std::string &Name);
void Clear();
diff --git a/apt-private/private-cmndline.cc b/apt-private/private-cmndline.cc
index 5d6fd3c2e..81352d757 100644
--- a/apt-private/private-cmndline.cc
+++ b/apt-private/private-cmndline.cc
@@ -3,6 +3,7 @@
#include <apt-pkg/cmndline.h>
#include <apt-pkg/configuration.h>
+#include <apt-pkg/fileutl.h>
#include <apt-pkg/pkgsystem.h>
#include <apt-pkg/init.h>
#include <apt-pkg/error.h>
@@ -322,8 +323,21 @@ void ParseCommandLine(CommandLine &CmdL, CommandLine::Dispatch * const Cmds, Com
Configuration * const * const Cnf, pkgSystem ** const Sys, int const argc, const char *argv[], bool(*ShowHelp)(CommandLine &CmdL))
{
CmdL = CommandLine(Args,_config);
- if ((Cnf != NULL && pkgInitConfig(**Cnf) == false) ||
- CmdL.Parse(argc,argv) == false ||
+ if (Cnf != NULL && pkgInitConfig(**Cnf) == false)
+ {
+ _error->DumpErrors();
+ exit(100);
+ }
+
+ if (likely(argc != 0 && argv[0] != NULL))
+ {
+ std::string const binary = flNotDir(argv[0]);
+ _config->Set("Binary", binary);
+ std::string const conf = "Binary::" + binary;
+ _config->MoveSubTree(conf.c_str(), NULL);
+ }
+
+ if (CmdL.Parse(argc,argv) == false ||
(Sys != NULL && pkgInitSystem(*_config, *Sys) == false))
{
if (_config->FindB("version") == true)
diff --git a/doc/apt.conf.5.xml b/doc/apt.conf.5.xml
index bb0c37ff8..2bb814257 100644
--- a/doc/apt.conf.5.xml
+++ b/doc/apt.conf.5.xml
@@ -54,6 +54,8 @@
configuration list - in which case it will be silently ignored.</para></listitem>
<listitem><para>the main configuration file specified by
<literal>Dir::Etc::main</literal></para></listitem>
+ <listitem><para>all options set in the binary specific configuration
+ subtree are moved into the root of the tree.</para></listitem>
<listitem><para>the command line options are applied to override the
configuration directives or to load even more configuration files.</para></listitem>
</orderedlist>
@@ -673,6 +675,24 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";};
</variablelist>
</refsect1>
+ <refsect1><title>Binary specific configuration</title>
+ <para>Especially with the introduction of the <command>apt</command> binary
+ it can be useful to set certain options only for a specific binary as
+ even options which look like they would effect only a certain binary like
+ <option>APT::Get::Show-Versions</option> effect
+ <command>apt-get</command> as well as <command>apt</command>.
+ </para>
+ <para>Setting an option for a specific binary only can be achieved by
+ setting the option inside the
+ <option>Binary::<replaceable>specific-binary</replaceable></option>
+ scope. Setting the option <option>APT::Get::Show-Versions</option> for
+ the <command>apt</command> only can e.g. by done by setting
+ <option>Binary::apt::APT::Get::Show-Versions</option> instead.</para>
+ <para>Note that as seen in the DESCRIPTION section further above you can't
+ set binary-specific options on the commandline itself nor in
+ configuration files loaded via the commandline.</para>
+ </refsect1>
+
<refsect1><title>Directories</title>
<para>The <literal>Dir::State</literal> section has directories that pertain to local
diff --git a/test/integration/test-apt-showlist-orgroup-in-recommends b/test/integration/test-apt-showlist-orgroup-in-recommends
index 929f7feb9..fea54f1ce 100755
--- a/test/integration/test-apt-showlist-orgroup-in-recommends
+++ b/test/integration/test-apt-showlist-orgroup-in-recommends
@@ -39,6 +39,17 @@ The following NEW packages will be installed:
simple
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Inst simple (1 unstable [all])
+Conf simple (1 unstable [all])' aptget install simple -s --install-recommends --install-suggests
+testsuccessequal 'Reading package lists...
+Building dependency tree...
+Suggested packages:
+ ccc
+Recommended packages:
+ bbb
+The following NEW packages will be installed:
+ simple
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst simple (1 unstable [all])
Conf simple (1 unstable [all])' aptget install simple -s --no-install-recommends
testsuccessequal 'Reading package lists...
Building dependency tree...
@@ -156,3 +167,34 @@ The following NEW packages will be installed:
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Inst versionedor (1 unstable [all])
Conf versionedor (1 unstable [all])' aptget install versionedor -s --no-install-recommends
+
+SHOWSUGGEST='Reading package lists...
+Building dependency tree...
+Suggested packages:
+ zzz
+Recommended packages:
+ xxx
+The following NEW packages will be installed:
+ orgroup4
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst orgroup4 (1 unstable [all])
+Conf orgroup4 (1 unstable [all])'
+INSTSUGGEST='Reading package lists...
+Building dependency tree...
+The following additional packages will be installed:
+ zzz
+Recommended packages:
+ xxx
+The following NEW packages will be installed:
+ orgroup4 zzz
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst orgroup4 (1 unstable [all])
+Inst zzz (1:1 unstable [all])
+Conf orgroup4 (1 unstable [all])
+Conf zzz (1:1 unstable [all])'
+testsuccessequal "$SHOWSUGGEST" aptget install orgroup4 -s
+testsuccessequal "$INSTSUGGEST" aptget install orgroup4 --install-suggests -s
+echo 'Binary::apt-get::APT::Install-Suggests "true";' > rootdir/etc/apt/apt.conf.d/99binaryspecific.conf
+testsuccessequal "$INSTSUGGEST" aptget install orgroup4 -s
+testsuccessequal "$SHOWSUGGEST" apt install orgroup4 -s
+testsuccessequal "$SHOWSUGGEST" aptget install orgroup4 -s --no-install-suggests
diff --git a/test/libapt/configuration_test.cc b/test/libapt/configuration_test.cc
index 647d8a4af..6300b5256 100644
--- a/test/libapt/configuration_test.cc
+++ b/test/libapt/configuration_test.cc
@@ -144,3 +144,20 @@ TEST(ConfigurationTest,Vector)
EXPECT_EQ("abel", vec[0]);
EXPECT_EQ("bravo", vec[1]);
}
+TEST(ConfigurationTest,Merge)
+{
+ Configuration Cnf;
+ Cnf.Set("Binary::apt::option::foo", "bar");
+ Cnf.Set("option::foo", "foo");
+
+ Cnf.MoveSubTree("Binary::apt", "Binary::apt2");
+ EXPECT_FALSE(Cnf.Exists("Binary::apt::option"));
+ EXPECT_TRUE(Cnf.Exists("option"));
+ EXPECT_EQ("foo", Cnf.Find("option::foo"));
+ EXPECT_EQ("bar", Cnf.Find("Binary::apt2::option::foo"));
+
+ Cnf.MoveSubTree("Binary::apt2", NULL);
+ EXPECT_FALSE(Cnf.Exists("Binary::apt2::option"));
+ EXPECT_TRUE(Cnf.Exists("option"));
+ EXPECT_EQ("bar", Cnf.Find("option::foo"));
+}