]> git.saurik.com Git - apt.git/commitdiff
add binary-specific options via Binary scope
authorDavid Kalnischkies <david@kalnischkies.de>
Fri, 16 Oct 2015 16:03:52 +0000 (18:03 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Wed, 4 Nov 2015 17:04:02 +0000 (18:04 +0100)
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.

apt-pkg/contrib/configuration.cc
apt-pkg/contrib/configuration.h
apt-private/private-cmndline.cc
doc/apt.conf.5.xml
test/integration/test-apt-showlist-orgroup-in-recommends
test/libapt/configuration_test.cc

index 203de158b5d536fff8e54c8c8aa2b03928f6be3d..d4bb72a8b61ea606e161163308f008e2941b588b 100644 (file)
@@ -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             /*{{{*/
 // ---------------------------------------------------------------------
 /* */
 // Configuration::Exists - Returns true if the Name exists             /*{{{*/
 // ---------------------------------------------------------------------
 /* */
index eacc26fda6ebf61834a0458ded2129250fad5da3..97a01e4cfa25f41cece02043b2507c79c5615058 100644 (file)
@@ -103,6 +103,8 @@ class Configuration
    bool Exists(const char *Name) const;
    bool ExistsAny(const char *Name) const;
 
    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();
    // clear a whole tree
    void Clear(const std::string &Name);
    void Clear();
index 5d6fd3c2e6bd851b938b608d580b8ea2f6e70f8c..81352d7579e8cd16bdacbae50dcaf9a523b65773 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <apt-pkg/cmndline.h>
 #include <apt-pkg/configuration.h>
 
 #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>
 #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);
       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)
        (Sys != NULL && pkgInitSystem(*_config, *Sys) == false))
    {
       if (_config->FindB("version") == true)
index bb0c37ff806b86456ed938de31bc02e6b917f269..2bb81425717c2c3fdcb709a5d98f90fa908d1b49 100644 (file)
@@ -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>
         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>
       <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>
 
    </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 
  <refsect1><title>Directories</title>
 
    <para>The <literal>Dir::State</literal> section has directories that pertain to local 
index 929f7feb9cfa6e17bbed851ea824d98c84492cfe..fea54f1ceb18a1decad53e4f70f823bd78fa16fe 100755 (executable)
@@ -29,6 +29,17 @@ Suggests: ccc | ddd (>> 2)'
 
 setupaptarchive
 
 
 setupaptarchive
 
+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 --install-recommends --install-suggests
 testsuccessequal 'Reading package lists...
 Building dependency tree...
 Suggested packages:
 testsuccessequal 'Reading package lists...
 Building dependency tree...
 Suggested packages:
@@ -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
 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
index 647d8a4af6377010a55f3fa2d3c632156a3be88a..6300b5256378d56846478173af67995f602c260c 100644 (file)
@@ -144,3 +144,20 @@ TEST(ConfigurationTest,Vector)
        EXPECT_EQ("abel", vec[0]);
        EXPECT_EQ("bravo", vec[1]);
 }
        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"));
+}