1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2026-05-22 10:15:16 +02:00

Allow --version and --help for version and help.

It is a bit confusing that --help and --version do not work like most command-line programs. For example, git allows either --help or help.

Make these work by making them shortcuts (not actual options) to the applicable commands.

The user will still need to use help (not --help) to get help on specific commands/options, but at least they can get to the main help (which will tell them this) via --help.
This commit is contained in:
David Steele
2024-01-22 12:00:13 -03:00
committed by GitHub
parent db5bcff3b4
commit 68db3075d7
3 changed files with 118 additions and 11 deletions
+15
View File
@@ -1,2 +1,17 @@
<release date="XXXX-XX-XX" version="2.51dev" title="UNDER DEVELOPMENT">
<release-core-list>
<release-improvement-list>
<release-item>
<github-pull-request id="2263"/>
<release-item-contributor-list>
<release-item-ideator id="greg.sabino.mullane"/>
<release-item-contributor id="david.steele"/>
<release-item-reviewer id="greg.sabino.mullane"/>
</release-item-contributor-list>
<p>Allow <br-setting>--version</br-setting> and <br-setting>--help</br-setting> for version and help.</p>
</release-item>
</release-improvement-list>
</release-core-list>
</release>
+43 -9
View File
@@ -1556,6 +1556,9 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
// Only the first non-option parameter should be treated as a command so track if the command has been set
bool commandSet = false;
unsigned int argIgnore = 0;
bool help = false;
bool version = false;
for (unsigned int argListIdx = 1; argListIdx < argListSize; argListIdx++)
{
@@ -1589,7 +1592,25 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
CfgParseOptionResult option = cfgParseOptionP(optionName, .prefixMatch = true);
if (!option.found)
{
// Check for --help shortcut to the help command
if (strcmp(arg, CFGCMD_HELP) == 0)
{
help = true;
argIgnore++;
continue;
}
// Else check for --version shortcut to the version command
else if (strcmp(arg, CFGCMD_VERSION) == 0)
{
version = true;
argIgnore++;
continue;
}
// Else invalid option
else
THROW_FMT(OptionInvalidError, "invalid option '--%s'", arg);
}
// If the option may have an argument (arguments are optional for boolean options)
if (!option.negate && !option.reset)
@@ -1749,13 +1770,6 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
config->help = true;
else
commandSet = true;
// Set command options
config->lockRequired = parseRuleCommand[config->command].lockRequired;
config->lockRemoteRequired = parseRuleCommand[config->command].lockRemoteRequired;
config->lockType = (LockType)parseRuleCommand[config->command].lockType;
config->logFile = parseRuleCommand[config->command].logFile;
config->logLevelDefault = (LogLevel)parseRuleCommand[config->command].logLevelDefault;
}
// Additional arguments are command arguments
else
@@ -1778,12 +1792,28 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
if (!commandSet && !config->help)
{
// If there are args then error
if (argListSize > 1)
if (argListSize - argIgnore > 1)
THROW_FMT(CommandRequiredError, "no command found");
// Otherwise set the command to help
// Output help if --help specified or --version not specified
if (help || !version)
{
config->help = true;
}
// Else output version
else
config->command = cfgCmdVersion;
}
// Set command options
if (config->command != cfgCmdNone)
{
config->lockRequired = parseRuleCommand[config->command].lockRequired;
config->lockRemoteRequired = parseRuleCommand[config->command].lockRemoteRequired;
config->lockType = (LockType)parseRuleCommand[config->command].lockType;
config->logFile = parseRuleCommand[config->command].logFile;
config->logLevelDefault = (LogLevel)parseRuleCommand[config->command].logLevelDefault;
}
// Error when parameters found but the command does not allow parameters
if (config->paramList != NULL && !config->help && !parseRuleCommand[config->command].parameterAllowed)
@@ -1797,6 +1827,10 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
// specific command and would like to display actual option values in the help.
if (config->command != cfgCmdNone && config->command != cfgCmdVersion && config->command != cfgCmdHelp)
{
// Error if --help or --version passed to command
if (help || version)
THROW_FMT(OptionInvalidError, "invalid option '--%s'", help ? CFGCMD_HELP : CFGCMD_VERSION);
// Phase 2: parse environment variables
// ---------------------------------------------------------------------------------------------------------------------
unsigned int environIdx = 0;
+58
View File
@@ -1542,6 +1542,64 @@ testRun(void)
TEST_RESULT_BOOL(cfgCommandHelp(), true, "help is set");
TEST_RESULT_INT(cfgCommand(), cfgCmdVersion, "command is version");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("help option");
argList = strLstNew();
strLstAddZ(argList, TEST_BACKREST_EXE);
strLstAddZ(argList, "--help");
TEST_RESULT_VOID(cfgParseP(storageTest, strLstSize(argList), strLstPtr(argList), .noResetLogLevel = true), "load config");
TEST_RESULT_BOOL(cfgCommandHelp(), true, "help is set");
TEST_RESULT_INT(cfgCommand(), cfgCmdNone, "command is none");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("version option");
argList = strLstNew();
strLstAddZ(argList, TEST_BACKREST_EXE);
strLstAddZ(argList, "--version");
TEST_RESULT_VOID(cfgParseP(storageTest, strLstSize(argList), strLstPtr(argList), .noResetLogLevel = true), "load config");
TEST_RESULT_BOOL(cfgCommandHelp(), false, "help is not set");
TEST_RESULT_INT(cfgCommand(), cfgCmdVersion, "command is version");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("help and version options");
argList = strLstNew();
strLstAddZ(argList, TEST_BACKREST_EXE);
strLstAddZ(argList, "--help");
strLstAddZ(argList, "--version");
TEST_RESULT_VOID(cfgParseP(storageTest, strLstSize(argList), strLstPtr(argList), .noResetLogLevel = true), "load config");
TEST_RESULT_BOOL(cfgCommandHelp(), true, "help is not set");
TEST_RESULT_INT(cfgCommand(), cfgCmdNone, "command is none");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("error on command with --help option");
argList = strLstNew();
strLstAddZ(argList, TEST_BACKREST_EXE);
strLstAddZ(argList, "--help");
strLstAddZ(argList, "backup");
TEST_ERROR(
cfgParseP(storageTest, strLstSize(argList), strLstPtr(argList), .noResetLogLevel = true), OptionInvalidError,
"invalid option '--help'");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("error on command with --version option");
argList = strLstNew();
strLstAddZ(argList, TEST_BACKREST_EXE);
strLstAddZ(argList, "--version");
strLstAddZ(argList, "backup");
TEST_ERROR(
cfgParseP(storageTest, strLstSize(argList), strLstPtr(argList), .noResetLogLevel = true), OptionInvalidError,
"invalid option '--version'");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("help command - should not fail on missing options");