Skip to content

Instantly share code, notes, and snippets.

@jamesob
Created November 8, 2019 21:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesob/778eb138a8fe41148f173c791727dcb8 to your computer and use it in GitHub Desktop.
Save jamesob/778eb138a8fe41148f173c791727dcb8 to your computer and use it in GitHub Desktop.
$ diff --color=never /home/james/.ackr/15934.ryanofsky.merge_settings_one_place/3.083c954/base.diff /home/james/.ackr/15934.ryanofsky.merge_settings_one_place/2.202e198/base.diff | sed -r "s/[[:cntrl:]]\[[0-9]{1,3}m//g" | xclip -in
2c2
< index ff4f071a3c..a14e44d2c0 100644
---
> index 82cc19d57c..ad6bf4e080 100644
5c5
< @@ -219,6 +219,7 @@ BITCOIN_CORE_H = \
---
> @@ -215,6 +215,7 @@ BITCOIN_CORE_H = \
13c13
< @@ -513,6 +514,7 @@ libbitcoin_util_a_SOURCES = \
---
> @@ -507,6 +508,7 @@ libbitcoin_util_a_SOURCES = \
22c22
< index 6d2b546a28..dd1ade5496 100644
---
> index 019e832cc6..b60f85da2f 100644
25c25
< @@ -152,6 +152,7 @@ BITCOIN_TESTS =\
---
> @@ -141,6 +141,7 @@ BITCOIN_TESTS =\
35c35
< index 0000000000..b0ee76ea6b
---
> index 0000000000..920d5021be
44a45
> +#include <test/setup_common.h>
46d46
< +#include <test/util/setup_common.h>
203c203
< index daf6d951bc..b9fcd97a8f 100644
---
> index 569ce53092..ba9d732cba 100644
279c279
< @@ -298,6 +299,7 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArg)
---
> @@ -244,6 +245,7 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArg)
287c287
< @@ -306,8 +308,8 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArg)
---
> @@ -252,8 +254,8 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArg)
298c298
< @@ -403,6 +405,7 @@ BOOST_AUTO_TEST_CASE(util_ReadConfigStream)
---
> @@ -349,6 +351,7 @@ BOOST_AUTO_TEST_CASE(util_ReadConfigStream)
306c306
< @@ -419,22 +422,25 @@ BOOST_AUTO_TEST_CASE(util_ReadConfigStream)
---
> @@ -365,22 +368,25 @@ BOOST_AUTO_TEST_CASE(util_ReadConfigStream)
347c347
< @@ -573,24 +579,25 @@ BOOST_AUTO_TEST_CASE(util_ReadConfigStream)
---
> @@ -519,24 +525,25 @@ BOOST_AUTO_TEST_CASE(util_ReadConfigStream)
388c388
< index 0000000000..af75fef310
---
> index 0000000000..06536d2ee1
391c391
< @@ -0,0 +1,169 @@
---
> @@ -0,0 +1,163 @@
403,407c403,411
< +enum class Source {
< + FORCED,
< + COMMAND_LINE,
< + CONFIG_FILE_NETWORK_SECTION,
< + CONFIG_FILE_DEFAULT_SECTION
---
> +struct Source {
> + SettingsSpan span;
> + bool forced = false;
> + bool config_file = false;
> + bool config_file_default_section = false;
> +
> + explicit Source(SettingsSpan span) : span(span) {}
> + Source& SetForced() noexcept { forced = true; return *this; }
> + Source& SetConfigFile(bool default_section) noexcept { config_file = true; config_file_default_section = default_section; return *this; }
410,414d413
< +//! Merge settings from multiple sources in precedence order:
< +//! Forced config > command line > config file network-specific section > config file default section
< +//!
< +//! This function is provided with a callback function fn that contains
< +//! specific logic for how to merge the sources.
418d416
< + // Merge in the forced settings
420c418
< + fn(SettingsSpan(*value), Source::FORCED);
---
> + fn(Source(SettingsSpan(*value)).SetForced());
422d419
< + // Merge in the command-line options
424c421
< + fn(SettingsSpan(*values), Source::COMMAND_LINE);
---
> + fn(Source(SettingsSpan(*values)));
426d422
< + // Merge in the network-specific section of the config file
430c426
< + fn(SettingsSpan(*values), Source::CONFIG_FILE_NETWORK_SECTION);
---
> + fn(Source(SettingsSpan(*values)).SetConfigFile(/* default_section= */ false));
434d429
< + // Merge in the default section of the config file
437c432
< + fn(SettingsSpan(*values), Source::CONFIG_FILE_DEFAULT_SECTION);
---
> + fn(Source(SettingsSpan(*values)).SetConfigFile(/* default_section= */ true));
450c445
< + MergeSettings(settings, section, name, [&](SettingsSpan span, Source source) {
---
> + MergeSettings(settings, section, name, [&](Source source) {
452,455c447,450
< + // setting even if non-negated setting would be ignored. A negated
< + // value in the default section is applied to network specific options,
< + // even though normal non-negated values there would be ignored.
< + const bool never_ignore_negated_setting = span.last_negated();
---
> + // setting in otherwise ignored sections. A negated value in the
> + // default section is applied to network specific options, even though
> + // non-negated values there would be ignored.
> + const bool never_ignore_negated_setting = source.span.last_negated();
460,462c455,456
< + // the config file the precedence is reversed for all settings except
< + // chain name settings.
< + const bool reverse_precedence = (source == Source::CONFIG_FILE_NETWORK_SECTION || source == Source::CONFIG_FILE_DEFAULT_SECTION) && !get_chain_name;
---
> + // the config file the precedence is reversed for most settings.
> + const bool reverse_precedence = source.config_file && !get_chain_name;
472c466
< + if (ignore_default_section_config && source == Source::CONFIG_FILE_DEFAULT_SECTION && !never_ignore_negated_setting) return;
---
> + if (ignore_default_section_config && source.config_file_default_section && !never_ignore_negated_setting) return;
475c469
< + if (skip_negated_command_line && span.last_negated()) return;
---
> + if (skip_negated_command_line && source.span.last_negated()) return;
480,482c474,476
< + if (!span.empty()) {
< + result = reverse_precedence ? span.begin()[0] : span.end()[-1];
< + } else if (span.last_negated()) {
---
> + if (!source.span.empty()) {
> + result = reverse_precedence ? source.span.begin()[0] : source.span.end()[-1];
> + } else if (source.span.last_negated()) {
497c491
< + MergeSettings(settings, section, name, [&](SettingsSpan span, Source source) {
---
> + MergeSettings(settings, section, name, [&](Source source) {
500,505c494,499
< + // command line will ignore earlier settings on the command line and
< + // ignore settings in the config file, unless the negated command line
< + // value is followed by non-negated value, in which case config file
< + // settings will be brought back from the dead (but earlier command
< + // line settings will still be ignored).
< + const bool add_zombie_config_values = (source == Source::CONFIG_FILE_NETWORK_SECTION || source == Source::CONFIG_FILE_DEFAULT_SECTION) && !prev_negated_empty;
---
> + // command line will discard earlier settings on the command line and
> + // settings in the config file, unless the negated command line value is
> + // followed by non-negated value, in which case config file settings
> + // will be brought back from the dead (but earlier command line settings
> + // will still be discarded).
> + const bool add_zombie_config_values = source.config_file && !prev_negated_empty;
508c502
< + if (ignore_default_section_config && source == Source::CONFIG_FILE_DEFAULT_SECTION) return;
---
> + if (ignore_default_section_config && source.config_file_default_section) return;
513c507
< + for (const auto& value : span) {
---
> + for (const auto& value : source.span) {
524c518
< + result_complete |= span.negated() > 0 || source == Source::FORCED;
---
> + result_complete |= source.span.negated() > 0 || source.forced;
527c521
< + prev_negated_empty |= span.last_negated() && result.empty();
---
> + prev_negated_empty |= source.span.last_negated() && result.empty();
536,538c530,532
< + MergeSettings(settings, section, name, [&](SettingsSpan span, Source source) {
< + if (span.empty()) return;
< + else if (source == Source::CONFIG_FILE_DEFAULT_SECTION) has_default_section_setting = true;
---
> + MergeSettings(settings, section, name, [&](Source source) {
> + if (source.span.empty()) return;
> + else if (source.config_file_default_section) has_default_section_setting = true;
655c649
< index 7da408eda5..2a2ae6fdf5 100644
---
> index 7da408eda5..8bcb13b742 100644
795c789
< @@ -282,34 +204,39 @@ public:
---
> @@ -282,34 +204,38 @@ public:
806d799
< + // Split section name from key name for keys like "testnet.foo" or "regtest.bar"
858c851
< @@ -331,22 +258,9 @@ const std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const
---
> @@ -331,22 +257,9 @@ const std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const
884c877
< @@ -375,7 +289,7 @@ void ArgsManager::SelectConfigNetwork(const std::string& network)
---
> @@ -375,7 +288,7 @@ void ArgsManager::SelectConfigNetwork(const std::string& network)
893c886
< @@ -408,49 +322,44 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin
---
> @@ -408,49 +321,43 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin
897d889
< + // Transform -foo to foo
963c955
< @@ -460,69 +369,42 @@ unsigned int ArgsManager::FlagsOfKnownArg(const std::string& key) const
---
> @@ -460,69 +367,42 @@ unsigned int ArgsManager::FlagsOfKnownArg(const std::string& key) const
1046c1038
< @@ -544,7 +426,7 @@ bool ArgsManager::SoftSetBoolArg(const std::string& strArg, bool fValue)
---
> @@ -544,7 +424,7 @@ bool ArgsManager::SoftSetBoolArg(const std::string& strArg, bool fValue)
1055c1047
< @@ -860,12 +742,15 @@ bool ArgsManager::ReadConfigStream(std::istream& stream, const std::string& file
---
> @@ -860,12 +740,15 @@ bool ArgsManager::ReadConfigStream(std::istream& stream, const std::string& file
1074c1066
< @@ -882,7 +767,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
---
> @@ -882,7 +765,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
1083,1092c1075,1076
< @@ -894,58 +779,64 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
< if (!ReadConfigStream(stream, confPath, error, ignore_invalid_keys)) {
< return false;
< }
< - // if there is an -includeconf in the override args, but it is empty, that means the user
< - // passed '-noincludeconf' on the command line, in which case we should not include anything
< - bool emptyIncludeConf;
< + // `-includeconf` cannot be included in the command line arguments except
< + // as `-noincludeconf` (which indicates that no conf file should be used).
< + bool use_conf_file{true};
---
> @@ -899,25 +782,31 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
> bool emptyIncludeConf;
1096,1100c1080,1081
< + if (auto* includes = util::FindKey(m_settings.command_line_options, "includeconf")) {
< + // ParseParameters() fails if a non-negated -includeconf is passed on the command-line
< + assert(util::SettingsSpan(*includes).last_negated());
< + use_conf_file = false;
< + }
---
> + const std::vector<util::SettingsValue>* const includes = util::FindKey(m_settings.command_line_options, "includeconf");
> + emptyIncludeConf = !(includes && util::SettingsSpan(*includes).last_negated());
1102,1103c1083
< - if (emptyIncludeConf) {
< + if (use_conf_file) {
---
> if (emptyIncludeConf) {
1112c1092
< + std::vector<std::string> conf_file_names;
---
> + std::vector<std::string> includeconf;
1123,1127d1102
< -
< - for (const std::string& to_include : includeconf) {
< - fsbridge::ifstream include_config(GetConfigFile(to_include));
< - if (include_config.good()) {
< - if (!ReadConfigStream(include_config, to_include, error, ignore_invalid_keys)) {
1131c1106
< + conf_file_names.push_back((*values)[i].get_str());
---
> + includeconf.push_back((*values)[i].get_str());
1143,1156c1118,1121
< +
< + for (const std::string& conf_file_name : conf_file_names) {
< + fsbridge::ifstream conf_file_stream(GetConfigFile(conf_file_name));
< + if (conf_file_stream.good()) {
< + if (!ReadConfigStream(conf_file_stream, conf_file_name, error, ignore_invalid_keys)) {
< return false;
< }
< - LogPrintf("Included configuration file %s\n", to_include);
< + LogPrintf("Included configuration file %s\n", conf_file_name);
< } else {
< - error = "Failed to include configuration file " + to_include;
< + error = "Failed to include configuration file " + conf_file_name;
< return false;
< }
---
> 
> for (const std::string& to_include : includeconf) {
> fsbridge::ifstream include_config(GetConfigFile(to_include));
> @@ -933,15 +822,14 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
1161c1126,1129
< - {
---
> + includeconf.clear();
> + add_includes(chain_id, /* skip= */ chain_includes);
> + add_includes({}, /* skip= */ default_includes);
> {
1164,1166c1132,1134
< - std::string chain_id_final = GetChainName();
< - if (chain_id_final != chain_id) {
< - // Also warn about recursive includeconf for the chain that was specified in one of the includeconfs
---
> std::string chain_id_final = GetChainName();
> if (chain_id_final != chain_id) {
> // Also warn about recursive includeconf for the chain that was specified in one of the includeconfs
1169,1181c1137,1138
< - }
< + conf_file_names.clear();
< + add_includes(chain_id, /* skip= */ chain_includes);
< + add_includes({}, /* skip= */ default_includes);
< + std::string chain_id_final = GetChainName();
< + if (chain_id_final != chain_id) {
< + // Also warn about recursive includeconf for the chain that was specified in one of the includeconfs
< + add_includes(chain_id_final);
< }
< - for (const std::string& to_include : includeconf) {
< - tfm::format(std::cerr, "warning: -includeconf cannot be used from included files; ignoring -includeconf=%s\n", to_include);
< + for (const std::string& conf_file_name : conf_file_names) {
< + tfm::format(std::cerr, "warning: -includeconf cannot be used from included files; ignoring -includeconf=%s\n", conf_file_name);
---
> + add_includes(chain_id_final);
> }
1183,1185c1140,1141
< }
< }
< @@ -961,9 +852,16 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
---
> for (const std::string& to_include : includeconf) {
> @@ -961,9 +849,16 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
1206c1162
< index 7452f186e6..e0b6371dc9 100644
---
> index 908a3c407d..774491516a 100644
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment