Merge bitcoin/bitcoin#24306: util: Make ArgsManager::GetPathArg more widely usable

60aa179d8f9a675efa2d78eaadc09e3ba450f50f Use GetPathArg where possible (Pavol Rusnak)
5b946edd73640c6ecdfb4cbac1d4351e634678dc util, refactor: Use GetPathArg to read "-settings" value (Ryan Ofsky)
687e655ae2970f2f13aca0267c7de86dc69be763 util: Add GetPathArg default path argument (Ryan Ofsky)

Pull request description:

  Improve `ArgsManager::GetPathArg` method added in recent PR #24265, so it is usable more places. This PR starts to use it for the `-settings` option. This can also be helpful for #24274 which is parsing more path options.

  - Add `GetPathArg` default argument so it is less awkward to use to parse options that have default values.
  - Fix `GetPathArg` negated argument handling. Return path{} not path{"0"} when path argument is negated.
  - Add unit tests for default and negated cases
  - Move `GetPathArg` method declaration next to `GetArg` declaration. The two methods are close substitutes for each, so this should help keep them consistent and make them more discoverable.

ACKs for top commit:
  w0xlt:
    Tested ACK 60aa179 on Ubuntu 21.10
  hebasto:
    re-ACK 60aa179d8f9a675efa2d78eaadc09e3ba450f50f

Tree-SHA512: 3d24b885d8bbeef39ea5d0556e2f09b9e5f4a21179cef11cbbbc1b84da29c8fb66ba698889054ce28d80bc25926687654c8532ed46054bf5b2dd1837866bd1cd
This commit is contained in:
MarcoFalke 2022-03-07 10:00:38 +01:00 committed by pasta
parent 6a51ab271d
commit d96983a327
No known key found for this signature in database
GPG Key ID: E2F3D7916E722D38
6 changed files with 43 additions and 23 deletions

View File

@ -111,8 +111,8 @@ int main(int argc, char** argv)
args.asymptote = parseAsymptote(argsman.GetArg("-asymptote", "")); args.asymptote = parseAsymptote(argsman.GetArg("-asymptote", ""));
args.is_list_only = argsman.GetBoolArg("-list", false); args.is_list_only = argsman.GetBoolArg("-list", false);
args.min_time = std::chrono::milliseconds(argsman.GetArg("-min_time", DEFAULT_MIN_TIME_MS)); args.min_time = std::chrono::milliseconds(argsman.GetArg("-min_time", DEFAULT_MIN_TIME_MS));
args.output_csv = fs::PathFromString(argsman.GetArg("-output_csv", "")); args.output_csv = argsman.GetPathArg("-output_csv");
args.output_json = fs::PathFromString(argsman.GetArg("-output_json", "")); args.output_json = argsman.GetPathArg("-output_json");
args.regex_filter = argsman.GetArg("-filter", DEFAULT_BENCH_FILTER); args.regex_filter = argsman.GetArg("-filter", DEFAULT_BENCH_FILTER);
benchmark::BenchRunner::RunAll(args); benchmark::BenchRunner::RunAll(args);

View File

@ -160,7 +160,7 @@ static const char* BITCOIN_PID_FILENAME = "dashd.pid";
static fs::path GetPidFile(const ArgsManager& args) static fs::path GetPidFile(const ArgsManager& args)
{ {
return AbsPathForConfigVal(fs::PathFromString(args.GetArg("-pid", BITCOIN_PID_FILENAME))); return AbsPathForConfigVal(args.GetPathArg("-pid", BITCOIN_PID_FILENAME));
} }
[[nodiscard]] static bool CreatePidFile(const ArgsManager& args) [[nodiscard]] static bool CreatePidFile(const ArgsManager& args)
@ -1566,10 +1566,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// Read asmap file if configured // Read asmap file if configured
std::vector<bool> asmap; std::vector<bool> asmap;
if (args.IsArgSet("-asmap")) { if (args.IsArgSet("-asmap")) {
fs::path asmap_path = fs::PathFromString(args.GetArg("-asmap", "")); fs::path asmap_path = args.GetPathArg("-asmap", DEFAULT_ASMAP_FILENAME);
if (asmap_path.empty()) {
asmap_path = fs::PathFromString(DEFAULT_ASMAP_FILENAME);
}
if (!asmap_path.is_absolute()) { if (!asmap_path.is_absolute()) {
asmap_path = gArgs.GetDataDirNet() / asmap_path; asmap_path = gArgs.GetDataDirNet() / asmap_path;
} }

View File

@ -77,7 +77,7 @@ void AddLoggingArgs(ArgsManager& argsman)
void SetLoggingOptions(const ArgsManager& args) void SetLoggingOptions(const ArgsManager& args)
{ {
LogInstance().m_print_to_file = !args.IsArgNegated("-debuglogfile"); LogInstance().m_print_to_file = !args.IsArgNegated("-debuglogfile");
LogInstance().m_file_path = AbsPathForConfigVal(fs::PathFromString(args.GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE))); LogInstance().m_file_path = AbsPathForConfigVal(args.GetPathArg("-debuglogfile", DEFAULT_DEBUGLOGFILE));
LogInstance().m_print_to_console = args.GetBoolArg("-printtoconsole", !args.GetBoolArg("-daemon", false)); LogInstance().m_print_to_console = args.GetBoolArg("-printtoconsole", !args.GetBoolArg("-daemon", false));
LogInstance().m_log_timestamps = args.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); LogInstance().m_log_timestamps = args.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS);
LogInstance().m_log_time_micros = args.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); LogInstance().m_log_time_micros = args.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS);

View File

@ -243,6 +243,24 @@ BOOST_AUTO_TEST_CASE(patharg)
ResetArgs("-dir=user/.bitcoin/.//"); ResetArgs("-dir=user/.bitcoin/.//");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), relative_path); BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), relative_path);
// Check negated and default argument handling. Specifying an empty argument
// is the same as not specifying the argument. This is convenient for
// scripting so later command line arguments can override earlier command
// line arguments or bitcoin.conf values. Currently the -dir= case cannot be
// distinguished from -dir case with no assignment, but #16545 would add the
// ability to distinguish these in the future (and treat the no-assign case
// like an imperative command or an error).
ResetArgs("");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir", "default"), fs::path{"default"});
ResetArgs("-dir=override");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir", "default"), fs::path{"override"});
ResetArgs("-dir=");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir", "default"), fs::path{"default"});
ResetArgs("-dir");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir", "default"), fs::path{"default"});
ResetArgs("-nodir");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir", "default"), fs::path{""});
} }
BOOST_AUTO_TEST_CASE(doubledash) BOOST_AUTO_TEST_CASE(doubledash)

View File

@ -407,9 +407,12 @@ std::optional<unsigned int> ArgsManager::GetArgFlags(const std::string& name) co
return std::nullopt; return std::nullopt;
} }
fs::path ArgsManager::GetPathArg(std::string pathlike_arg) const fs::path ArgsManager::GetPathArg(std::string arg, const fs::path& default_value) const
{ {
auto result = fs::PathFromString(GetArg(pathlike_arg, "")).lexically_normal(); if (IsArgNegated(arg)) return fs::path{};
std::string path_str = GetArg(arg, "");
if (path_str.empty()) return default_value;
fs::path result = fs::PathFromString(path_str).lexically_normal();
// Remove trailing slash, if present. // Remove trailing slash, if present.
return result.has_filename() ? result : result.parent_path(); return result.has_filename() ? result : result.parent_path();
} }
@ -544,12 +547,12 @@ bool ArgsManager::InitSettings(std::string& error)
bool ArgsManager::GetSettingsPath(fs::path* filepath, bool temp) const bool ArgsManager::GetSettingsPath(fs::path* filepath, bool temp) const
{ {
if (IsArgNegated("-settings")) { fs::path settings = GetPathArg("-settings", fs::path{BITCOIN_SETTINGS_FILENAME});
if (settings.empty()) {
return false; return false;
} }
if (filepath) { if (filepath) {
std::string settings = GetArg("-settings", BITCOIN_SETTINGS_FILENAME); *filepath = fsbridge::AbsPathJoin(GetDataDirNet(), temp ? settings + ".tmp" : settings);
*filepath = fsbridge::AbsPathJoin(GetDataDirNet(), fs::PathFromString(temp ? settings + ".tmp" : settings));
} }
return true; return true;
} }

View File

@ -283,16 +283,6 @@ protected:
*/ */
const std::map<std::string, std::vector<util::SettingsValue>> GetCommandLineArgs() const; const std::map<std::string, std::vector<util::SettingsValue>> GetCommandLineArgs() const;
/**
* Get a normalized path from a specified pathlike argument
*
* It is guaranteed that the returned path has no trailing slashes.
*
* @param pathlike_arg Pathlike argument to get a path from (e.g., "-datadir", "-blocksdir" or "-walletdir")
* @return Normalized path which is get from a specified pathlike argument
*/
fs::path GetPathArg(std::string pathlike_arg) const;
/** /**
* Get blocks directory path * Get blocks directory path
* *
@ -357,6 +347,18 @@ protected:
*/ */
std::string GetArg(const std::string& strArg, const std::string& strDefault) const; std::string GetArg(const std::string& strArg, const std::string& strDefault) const;
/**
* Return path argument or default value
*
* @param arg Argument to get a path from (e.g., "-datadir", "-blocksdir" or "-walletdir")
* @param default_value Optional default value to return instead of the empty path.
* @return normalized path if argument is set, with redundant "." and ".."
* path components and trailing separators removed (see patharg unit test
* for examples or implementation for details). If argument is empty or not
* set, default_value is returned unchanged.
*/
fs::path GetPathArg(std::string arg, const fs::path& default_value = {}) const;
/** /**
* Return integer argument or default value * Return integer argument or default value
* *