mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 16:42:05 +00:00
Added dashed-settings and support for unicode dash in cli arguments
This commit is contained in:
parent
5ebf66819b
commit
1ec5773dc6
@ -3,13 +3,29 @@
|
||||
#include <Poco/Util/LayeredConfiguration.h>
|
||||
#include <Poco/Util/MapConfiguration.h>
|
||||
|
||||
|
||||
void argsToConfig(const Poco::Util::Application::ArgVec & argv, Poco::Util::LayeredConfiguration & config, int priority)
|
||||
void argsToConfig(const Poco::Util::Application::ArgVec & argv,
|
||||
Poco::Util::LayeredConfiguration & config,
|
||||
int priority,
|
||||
const std::unordered_set<std::string>* alias_names)
|
||||
{
|
||||
/// Parsing all args and converting to config layer
|
||||
/// Test: -- --1=1 --1=2 --3 5 7 8 -9 10 -11=12 14= 15== --16==17 --=18 --19= --20 21 22 --23 --24 25 --26 -27 28 ---29=30 -- ----31 32 --33 3-4
|
||||
Poco::AutoPtr<Poco::Util::MapConfiguration> map_config = new Poco::Util::MapConfiguration;
|
||||
std::string key;
|
||||
|
||||
auto add_arg = [&map_config, &alias_names](const std::string & k, const std::string & v)
|
||||
{
|
||||
map_config->setString(k, v);
|
||||
|
||||
if (alias_names && !alias_names->contains(k))
|
||||
{
|
||||
std::string alias_key = k;
|
||||
std::replace(alias_key.begin(), alias_key.end(), '-', '_');
|
||||
if (alias_names->contains(alias_key))
|
||||
map_config->setString(alias_key, v);
|
||||
}
|
||||
};
|
||||
|
||||
for (const auto & arg : argv)
|
||||
{
|
||||
auto key_start = arg.find_first_not_of('-');
|
||||
@ -19,7 +35,7 @@ void argsToConfig(const Poco::Util::Application::ArgVec & argv, Poco::Util::Laye
|
||||
// old saved '--key', will set to some true value "1"
|
||||
if (!key.empty() && pos_minus != std::string::npos && pos_minus < key_start)
|
||||
{
|
||||
map_config->setString(key, "1");
|
||||
add_arg(key, "1");
|
||||
key = "";
|
||||
}
|
||||
|
||||
@ -29,7 +45,7 @@ void argsToConfig(const Poco::Util::Application::ArgVec & argv, Poco::Util::Laye
|
||||
{
|
||||
if (pos_minus == std::string::npos || pos_minus > key_start)
|
||||
{
|
||||
map_config->setString(key, arg);
|
||||
add_arg(key, arg);
|
||||
}
|
||||
key = "";
|
||||
}
|
||||
@ -55,7 +71,7 @@ void argsToConfig(const Poco::Util::Application::ArgVec & argv, Poco::Util::Laye
|
||||
if (arg.size() > pos_eq)
|
||||
value = arg.substr(pos_eq + 1);
|
||||
|
||||
map_config->setString(key, value);
|
||||
add_arg(key, value);
|
||||
key = "";
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <Poco/Util/Application.h>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace Poco::Util
|
||||
{
|
||||
@ -8,4 +10,7 @@ class LayeredConfiguration; // NOLINT(cppcoreguidelines-virtual-class-destructor
|
||||
}
|
||||
|
||||
/// Import extra command line arguments to configuration. These are command line arguments after --.
|
||||
void argsToConfig(const Poco::Util::Application::ArgVec & argv, Poco::Util::LayeredConfiguration & config, int priority);
|
||||
void argsToConfig(const Poco::Util::Application::ArgVec & argv,
|
||||
Poco::Util::LayeredConfiguration & config,
|
||||
int priority,
|
||||
const std::unordered_set<std::string>* registered_alias_names = nullptr);
|
||||
|
@ -68,6 +68,7 @@
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <regex>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "config_version.h"
|
||||
@ -120,6 +121,7 @@ namespace ProfileEvents
|
||||
namespace
|
||||
{
|
||||
constexpr UInt64 THREAD_GROUP_ID = 0;
|
||||
const std::string UNICODE_DASH = "—";
|
||||
}
|
||||
|
||||
namespace DB
|
||||
@ -2395,6 +2397,54 @@ struct TransparentStringHash
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* This functor is used to parse command line arguments and replace dashes with underscores,
|
||||
* allowing options to be specified using either dashes or underscores.
|
||||
*/
|
||||
class OptionsAliasParser
|
||||
{
|
||||
public:
|
||||
explicit OptionsAliasParser(const boost::program_options::options_description& options)
|
||||
{
|
||||
options_names.reserve(options.options().size());
|
||||
for (const auto& option : options.options())
|
||||
options_names.insert(option->long_name());
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses arguments by replacing dashes with underscores, and matches the resulting name with known options
|
||||
* Implements boost::program_options::ext_parser logic
|
||||
*/
|
||||
std::pair<std::string, std::string> operator()(const std::string& token) const
|
||||
{
|
||||
if (token.find("--") != 0)
|
||||
return {};
|
||||
std::string arg = token.substr(2);
|
||||
|
||||
// divide token by '=' to separate key and value if options style=long_allow_adjacent
|
||||
auto pos_eq = arg.find('=');
|
||||
std::string key = arg.substr(0, pos_eq);
|
||||
|
||||
if (options_names.contains(key))
|
||||
// option does not require any changes, because it is already correct
|
||||
return {};
|
||||
|
||||
std::replace(key.begin(), key.end(), '-', '_');
|
||||
if (!options_names.contains(key))
|
||||
// after replacing '-' with '_' argument is still unknown
|
||||
return {};
|
||||
|
||||
std::string value;
|
||||
if (pos_eq != std::string::npos && pos_eq < arg.size())
|
||||
value = arg.substr(pos_eq + 1);
|
||||
|
||||
return {key, value};
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_set<std::string> options_names;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -2445,7 +2495,10 @@ void ClientBase::parseAndCheckOptions(OptionsDescription & options_description,
|
||||
}
|
||||
|
||||
/// Parse main commandline options.
|
||||
auto parser = po::command_line_parser(arguments).options(options_description.main_description.value()).allow_unregistered();
|
||||
auto parser = po::command_line_parser(arguments)
|
||||
.options(options_description.main_description.value())
|
||||
.extra_parser(OptionsAliasParser(options_description.main_description.value()))
|
||||
.allow_unregistered();
|
||||
po::parsed_options parsed = parser.run();
|
||||
|
||||
/// Check unrecognized options without positional options.
|
||||
@ -2487,6 +2540,11 @@ void ClientBase::init(int argc, char ** argv)
|
||||
|
||||
readArguments(argc, argv, common_arguments, external_tables_arguments, hosts_and_ports_arguments);
|
||||
|
||||
/// Support for Unicode dashes
|
||||
/// Interpret Unicode dash as default double-dash
|
||||
for (auto & arg : common_arguments)
|
||||
arg = std::regex_replace(arg, std::regex(UNICODE_DASH), "--");
|
||||
|
||||
po::variables_map options;
|
||||
OptionsDescription options_description;
|
||||
options_description.main_description.emplace(createOptionsDescription("Main options", terminal_width));
|
||||
@ -2660,7 +2718,14 @@ void ClientBase::init(int argc, char ** argv)
|
||||
profile_events.delay_ms = options["profile-events-delay-ms"].as<UInt64>();
|
||||
|
||||
processOptions(options_description, options, external_tables_arguments, hosts_and_ports_arguments);
|
||||
argsToConfig(common_arguments, config(), 100);
|
||||
{
|
||||
std::unordered_set<std::string> alias_names;
|
||||
alias_names.reserve(options_description.main_description->options().size());
|
||||
for (const auto& option : options_description.main_description->options())
|
||||
alias_names.insert(option->long_name());
|
||||
argsToConfig(common_arguments, config(), 100, &alias_names);
|
||||
}
|
||||
|
||||
clearPasswordFromCommandLine(argc, argv);
|
||||
|
||||
/// Limit on total memory usage
|
||||
|
@ -0,0 +1,12 @@
|
||||
Test 1: Check that you can specify options with a dashes, not an underscores
|
||||
Test 1.1: Check option from config - server_logs_file
|
||||
1
|
||||
0
|
||||
1
|
||||
0
|
||||
1
|
||||
0
|
||||
Test 1.1: Check some option from Settings.h - allow_deprecated_syntax_for_merge_tree
|
||||
0
|
||||
Test 2: check that unicode dash processed correctly
|
||||
1
|
44
tests/queries/0_stateless/02718_cli_dashed_options_parsing.sh
Executable file
44
tests/queries/0_stateless/02718_cli_dashed_options_parsing.sh
Executable file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CURDIR"/../shell_config.sh
|
||||
|
||||
file_name=${CLICKHOUSE_TEST_UNIQUE_NAME}
|
||||
file_name_1=${file_name}_1
|
||||
file_name_2=${file_name}_2
|
||||
file_name_3=${file_name}_3
|
||||
|
||||
#################
|
||||
echo "Test 1: Check that you can specify options with a dashes, not an underscores"
|
||||
|
||||
[[ -e $file_name_1 ]] && rm $file_name_1
|
||||
[[ -e $file_name_2 ]] && rm $file_name_2
|
||||
[[ -e $file_name_3 ]] && rm $file_name_3
|
||||
|
||||
echo "Test 1.1: Check option from config - server_logs_file"
|
||||
|
||||
$CLICKHOUSE_LOCAL --log-level=debug --server-logs-file=$file_name_1 -q "SELECT 1;" 2> /dev/null
|
||||
ls | grep -q $file_name_1
|
||||
echo $?
|
||||
$CLICKHOUSE_LOCAL --log-level=debug --server-logs-file $file_name_2 -q "SELECT 1;" 2> /dev/null
|
||||
ls | grep -q $file_name_2
|
||||
echo $?
|
||||
$CLICKHOUSE_LOCAL --log-level=debug --server_logs_file $file_name_3 -q "SELECT 1;" 2> /dev/null
|
||||
ls | grep -q $file_name_3
|
||||
echo $?
|
||||
|
||||
echo "Test 1.1: Check some option from Settings.h - allow_deprecated_syntax_for_merge_tree"
|
||||
|
||||
$CLICKHOUSE_CLIENT --query="DROP TABLE IF EXISTS test";
|
||||
$CLICKHOUSE_CLIENT --allow-deprecated-syntax-for-merge-tree=1 --query="CREATE TABLE test (d Date, s String) ENGINE = MergeTree(d, s, 8192)";
|
||||
$CLICKHOUSE_CLIENT --query="DROP TABLE test";
|
||||
echo $?
|
||||
|
||||
#################
|
||||
echo "Test 2: check that unicode dash processed correctly"
|
||||
$CLICKHOUSE_LOCAL —query "SELECT 1";
|
||||
|
||||
rm $file_name_1
|
||||
rm $file_name_2
|
||||
rm $file_name_3
|
Loading…
Reference in New Issue
Block a user