From: David Kalnischkies Date: Fri, 16 Oct 2015 16:03:52 +0000 (+0200) Subject: add binary-specific options via Binary scope X-Git-Tag: 1.1_exp15~30 X-Git-Url: https://git.saurik.com/apt.git/commitdiff_plain/c3ded84c6f99bda4caf63c8662416ffb0189d31b 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. --- 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 #include +#include #include #include #include @@ -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. the main configuration file specified by Dir::Etc::main + all options set in the binary specific configuration + subtree are moved into the root of the tree. the command line options are applied to override the configuration directives or to load even more configuration files. @@ -673,6 +675,24 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";}; + Binary specific configuration + Especially with the introduction of the apt 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 + effect + apt-get as well as apt. + + Setting an option for a specific binary only can be achieved by + setting the option inside the + + scope. Setting the option for + the apt only can e.g. by done by setting + instead. + 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. + + Directories The Dir::State 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 @@ -29,6 +29,17 @@ Suggests: ccc | ddd (>> 2)' 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: @@ -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")); +}