1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2026-06-20 01:17:49 +02:00

Add default type for current pgbackrest binary.

These defaults were being set in cfgLoadUpdate() but they can be better documented if they are part of the option rules. This is part of a general trend to move away from custom-coded defaults.
This commit is contained in:
David Steele
2025-05-08 09:16:30 -04:00
parent 6869543b7a
commit 1e98684148
21 changed files with 263 additions and 132 deletions
+1
View File
@@ -106,6 +106,7 @@ option:
# Options that are not used but must be present for modules to compile. All must have a default or not be required. # Options that are not used but must be present for modules to compile. All must have a default or not be required.
#--------------------------------------------------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------------------------------------------------
beta: {type: boolean, default: false, command: {noop: {}}} beta: {type: boolean, default: false, command: {noop: {}}}
cmd: {type: string, default-type: dynamic, default: bin, command: {noop: {}}}
compress-level-network: {type: string, required: false, command: {noop: {}}} compress-level-network: {type: string, required: false, command: {noop: {}}}
config: { config: {
type: string, internal: true, default-type: literal, default: CFGOPTDEF_CONFIG_PATH "/" PROJECT_CONFIG_FILE, negate: true} type: string, internal: true, default-type: literal, default: CFGOPTDEF_CONFIG_PATH "/" PROJECT_CONFIG_FILE, negate: true}
+1
View File
@@ -7,6 +7,7 @@
<operation-general> <operation-general>
<option-list> <option-list>
<option id="beta"><summary></summary><text><p></p></text></option> <option id="beta"><summary></summary><text><p></p></text></option>
<option id="cmd"><summary></summary><text><p></p></text></option>
<option id="config"><summary></summary><text><p></p></text></option> <option id="config"><summary></summary><text><p></p></text></option>
<option id="config-path"><summary></summary><text><p></p></text></option> <option id="config-path"><summary></summary><text><p></p></text></option>
<option id="config-include-path"><summary></summary><text><p></p></text></option> <option id="config-include-path"><summary></summary><text><p></p></text></option>
+7 -1
View File
@@ -49,7 +49,13 @@ referenceOptionRender(
const String *const defaultValue = const String *const defaultValue =
optCmdCfg != NULL && optCmdCfg->defaultValue != NULL ? optCmdCfg->defaultValue : optCfg->defaultValue; optCmdCfg != NULL && optCmdCfg->defaultValue != NULL ? optCmdCfg->defaultValue : optCfg->defaultValue;
if (defaultValue != NULL) if (optCfg->defaultType == defaultTypeDynamic)
{
ASSERT(strEqZ(optCfg->defaultValue, "bin"));
strLstAddZ(blockList, "default: [path of executed pgbackrest binary]");
}
else if (defaultValue != NULL)
{ {
if (strEq(optCfg->type, OPT_TYPE_BOOLEAN_STR)) if (strEq(optCfg->type, OPT_TYPE_BOOLEAN_STR))
strLstAddFmt(blockList, "default: %s", strEqZ(defaultValue, "true") ? "y" : "n"); strLstAddFmt(blockList, "default: %s", strEqZ(defaultValue, "true") ? "y" : "n");
+12 -4
View File
@@ -237,6 +237,8 @@ optionGroup:
# #
# default-type: # default-type:
# If 'literal' then default a string output it as-is without quoting. This allows C defines to be used as defaults. # If 'literal' then default a string output it as-is without quoting. This allows C defines to be used as defaults.
# if 'dynamic' then default is a specially calculated value:
# bin - the value of argv[0] on execution
# #
# negate: # negate:
# All config file boolean options automatically may be negated. This setting is used to maintain backward compatibility with older # All config file boolean options automatically may be negated. This setting is used to maintain backward compatibility with older
@@ -727,7 +729,8 @@ option:
cmd: cmd:
section: global section: global
type: string type: string
required: false default-type: dynamic
default: bin
command: command:
archive-get: {} archive-get: {}
archive-push: {} archive-push: {}
@@ -753,6 +756,7 @@ option:
cmd-ssh: cmd-ssh:
inherit: cmd inherit: cmd
required: true required: true
default-type: quote
default: ssh default: ssh
# Option is deprecated and should not be referenced outside of cfgLoadUpdateOption() # Option is deprecated and should not be referenced outside of cfgLoadUpdateOption()
@@ -1518,7 +1522,8 @@ option:
section: stanza section: stanza
group: pg group: pg
type: string type: string
required: false default-type: dynamic
default: bin
command: command:
backup: {} backup: {}
check: {} check: {}
@@ -1540,7 +1545,6 @@ option:
inherit: pg-host-cmd inherit: pg-host-cmd
default-type: literal default-type: literal
default: CFGOPTDEF_CONFIG_PATH "/" PROJECT_CONFIG_FILE default: CFGOPTDEF_CONFIG_PATH "/" PROJECT_CONFIG_FILE
required: true
deprecate: deprecate:
db-config: {} db-config: {}
db?-config: {} db?-config: {}
@@ -1562,6 +1566,8 @@ option:
pg-host-port: pg-host-port:
inherit: pg-host-cmd inherit: pg-host-cmd
type: integer type: integer
default-type: quote
default: ~
required: false required: false
allow-range: [0, 65535] allow-range: [0, 65535]
deprecate: deprecate:
@@ -1570,6 +1576,7 @@ option:
pg-host-user: pg-host-user:
inherit: pg-host-cmd inherit: pg-host-cmd
default-type: quote
default: postgres default: postgres
required: false required: false
deprecate: deprecate:
@@ -2158,7 +2165,8 @@ option:
section: global section: global
group: repo group: repo
type: string type: string
required: false default-type: dynamic
default: bin
command: command:
annotate: {} annotate: {}
archive-get: {} archive-get: {}
+5 -1
View File
@@ -833,8 +833,12 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c
} }
else if (strEqZ(optDef.value, "default-type")) else if (strEqZ(optDef.value, "default-type"))
{ {
if (strEqZ(optDefVal.value, "literal")) if (strEqZ(optDefVal.value, "quote"))
optRaw.defaultType = defaultTypeQuote;
else if (strEqZ(optDefVal.value, "literal"))
optRaw.defaultType = defaultTypeLiteral; optRaw.defaultType = defaultTypeLiteral;
else if (strEqZ(optDefVal.value, "dynamic"))
optRaw.defaultType = defaultTypeDynamic;
else else
{ {
THROW_FMT( THROW_FMT(
+1
View File
@@ -13,6 +13,7 @@ typedef enum
{ {
defaultTypeQuote = 0, defaultTypeQuote = 0,
defaultTypeLiteral, defaultTypeLiteral,
defaultTypeDynamic,
} DefaultType; } DefaultType;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
+52 -1
View File
@@ -511,7 +511,11 @@ bldCfgRenderDefault(
" PARSE_RULE_OPTIONAL_DEFAULT\n" " PARSE_RULE_OPTIONAL_DEFAULT\n"
" (\n"); " (\n");
if (!strEq(optType, OPT_TYPE_STRING_STR) && !strEq(optType, OPT_TYPE_PATH_STR)) if (defaultType == defaultTypeDynamic)
{
strCatFmt(result, " PARSE_RULE_DEFAULT_DYNAMIC(%s),\n", strZ(bldEnum("", defaultValue)));
}
else if (!strEq(optType, OPT_TYPE_STRING_STR) && !strEq(optType, OPT_TYPE_PATH_STR))
strCatFmt(result, " %s,\n", strZ(bldCfgRenderScalar(defaultValue, optType))); strCatFmt(result, " %s,\n", strZ(bldCfgRenderScalar(defaultValue, optType)));
else else
{ {
@@ -538,6 +542,10 @@ bldCfgRenderValueAdd(const String *optType, const DefaultType defaultType, const
{ {
ASSERT(!strEq(optType, OPT_TYPE_BOOLEAN_STR) && !strEq(optType, OPT_TYPE_HASH_STR) && !strEq(optType, OPT_TYPE_LIST_STR)); ASSERT(!strEq(optType, OPT_TYPE_BOOLEAN_STR) && !strEq(optType, OPT_TYPE_HASH_STR) && !strEq(optType, OPT_TYPE_LIST_STR));
// Dynamic defaults are generated at runtime and do not need to be added to a static values list
if (defaultType == defaultTypeDynamic)
return;
// Remap path to string // Remap path to string
if (strEq(optType, OPT_TYPE_PATH_STR)) if (strEq(optType, OPT_TYPE_PATH_STR))
optType = OPT_TYPE_STRING_STR; optType = OPT_TYPE_STRING_STR;
@@ -824,6 +832,8 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co
// Option rules // Option rules
// ----------------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------------
StringList *const dynamicDefaultList = strLstNew();
strCatZ( strCatZ(
config, config,
"\n" "\n"
@@ -855,6 +865,10 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co
const BldCfgOption *const opt = lstGet(bldCfg.optList, optIdx); const BldCfgOption *const opt = lstGet(bldCfg.optList, optIdx);
String *const configOpt = strNew(); String *const configOpt = strNew();
// Build list of dynamic defaults
if (opt->defaultType == defaultTypeDynamic)
strLstAddIfMissing(dynamicDefaultList, opt->defaultValue);
if (optIdx != 0) if (optIdx != 0)
strCatZ(config, COMMENT_SEPARATOR "\n"); strCatZ(config, COMMENT_SEPARATOR "\n");
@@ -866,6 +880,9 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co
" PARSE_RULE_OPTION_TYPE(%s),\n", " PARSE_RULE_OPTION_TYPE(%s),\n",
strZ(opt->name), strZ(bldEnum("", opt->type))); strZ(opt->name), strZ(bldEnum("", opt->type)));
if (opt->defaultType == defaultTypeDynamic)
strCatZ(configOpt, " PARSE_RULE_OPTION_DEFAULT_TYPE(Dynamic),\n");
if (opt->boolLike) if (opt->boolLike)
strCatZ(configOpt, " PARSE_RULE_OPTION_BOOL_LIKE(true),\n"); strCatZ(configOpt, " PARSE_RULE_OPTION_BOOL_LIKE(true),\n");
@@ -1261,6 +1278,40 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co
configVal, configVal,
bldCfgRenderValueRender(OPT_TYPE_TIME_STR, ruleValMap, label, "unsigned int", "Time", "Time", "TIME", "val/time")); bldCfgRenderValueRender(OPT_TYPE_TIME_STR, ruleValMap, label, "unsigned int", "Time", "Time", "TIME", "val/time"));
// Dynamic default values
// -----------------------------------------------------------------------------------------------------------------------------
strCatZ(
configVal,
"\n"
COMMENT_BLOCK_BEGIN "\n"
"Dynamic default values\n"
COMMENT_BLOCK_END "\n");
strCatFmt(
configVal, "%s\n",
strZ(
bldDefineRender(
STRDEF("PARSE_RULE_DEFAULT_DYNAMIC(value)"),
strNewFmt(
"PARSE_RULE_U32_%zu(parseRuleDefaultDynamic##value)",
bldCfgRenderVar128Size(strLstSize(dynamicDefaultList) - 1)))));
strCatZ(
configVal,
"\ntypedef enum\n"
"{\n");
for (unsigned int dynamicDefaultIdx = 0; dynamicDefaultIdx < strLstSize(dynamicDefaultList); dynamicDefaultIdx++)
{
strCatFmt(
configVal, " %s,\n",
zNewFmt("parseRuleDefaultDynamic%s", strZ(bldEnum("", strLstGet(dynamicDefaultList, dynamicDefaultIdx)))));
}
strCatZ(
configVal,
"} ParseRuleDefaultDynamic;\n");
// Write to storage // Write to storage
// ----------------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------------
bldPut( bldPut(
-2
View File
@@ -800,7 +800,6 @@
<p>Required only if the path to the <backrest/> command is different on the local and repository hosts. If not defined, the repository host command will be set the same as the local command.</p> <p>Required only if the path to the <backrest/> command is different on the local and repository hosts. If not defined, the repository host command will be set the same as the local command.</p>
</text> </text>
<default>same as local</default>
<example>/usr/lib/backrest/bin/pgbackrest</example> <example>/usr/lib/backrest/bin/pgbackrest</example>
</config-key> </config-key>
@@ -1798,7 +1797,6 @@
<p>Required only if the path to the <backrest/> command is different on the local and <postgres/> hosts. If not defined, the <postgres/> host command will be set the same as the local command.</p> <p>Required only if the path to the <backrest/> command is different on the local and <postgres/> hosts. If not defined, the <postgres/> host command will be set the same as the local command.</p>
</text> </text>
<default>same as local</default>
<example>/usr/lib/backrest/bin/pgbackrest</example> <example>/usr/lib/backrest/bin/pgbackrest</example>
</config-key> </config-key>
+1 -41
View File
@@ -422,51 +422,11 @@ cfgOptionDefault(const ConfigOption optionId)
ConfigOptionData *const option = &configLocal->option[optionId]; ConfigOptionData *const option = &configLocal->option[optionId];
if (option->defaultValue == NULL) if (option->defaultValue == NULL)
option->defaultValue = cfgParseOptionDefault(cfgCommand(), optionId); option->defaultValue = cfgParseOptionDefault(cfgCommand(), optionId, cfgBin());
FUNCTION_TEST_RETURN_CONST(STRING, option->defaultValue); FUNCTION_TEST_RETURN_CONST(STRING, option->defaultValue);
} }
FN_EXTERN void
cfgOptionDefaultSet(const ConfigOption optionId, const Variant *defaultValue)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_PARAM(VARIANT, defaultValue);
FUNCTION_TEST_END();
ASSERT(optionId < CFG_OPTION_TOTAL);
ASSERT(cfgInited());
ASSERT(configLocal->option[optionId].valid);
ASSERT(cfgParseOptionDataType(optionId) == cfgOptDataTypeString);
MEM_CONTEXT_BEGIN(configLocal->memContext)
{
// Duplicate into this context
defaultValue = varDup(defaultValue);
// Set the default value
ConfigOptionData *const option = &configLocal->option[optionId];
option->defaultValue = varStr(defaultValue);
// Copy the value to option indexes that are marked as default so the default can be retrieved quickly
for (unsigned int optionIdx = 0; optionIdx < cfgOptionIdxTotal(optionId); optionIdx++)
{
ConfigOptionValue *const optionValue = &option->index[optionIdx];
if (optionValue->source == cfgSourceDefault)
{
optionValue->set = true;
optionValue->value.string = varStr(defaultValue);
optionValue->display = NULL;
}
}
}
MEM_CONTEXT_END();
FUNCTION_TEST_RETURN_VOID();
}
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/
FN_EXTERN const String * FN_EXTERN const String *
cfgOptionDisplayVar(const Variant *const value, const ConfigOptionType optionType) cfgOptionDisplayVar(const Variant *const value, const ConfigOptionType optionType)
-4
View File
@@ -255,10 +255,6 @@ FN_EXTERN void cfgCommandSet(ConfigCommand commandId, ConfigCommandRole commandR
// Path to current pgbackrest binary // Path to current pgbackrest binary
FN_EXTERN const String *cfgBin(void); FN_EXTERN const String *cfgBin(void);
// Set option default. Option defaults are generally not set in advance because the vast majority of them are never used. It is more
// efficient to generate them when they are requested. Some defaults are (e.g. the exe path) are set at runtime.
FN_EXTERN void cfgOptionDefaultSet(ConfigOption optionId, const Variant *defaultValue);
// Was the option negated? // Was the option negated?
FN_EXTERN bool cfgOptionIdxNegate(ConfigOption optionId, unsigned int optionIdx); FN_EXTERN bool cfgOptionIdxNegate(ConfigOption optionId, unsigned int optionIdx);
-12
View File
@@ -119,18 +119,6 @@ cfgLoadUpdateOption(void)
} }
} }
// Set default for cmd
if (cfgOptionValid(cfgOptCmd))
cfgOptionDefaultSet(cfgOptCmd, VARSTR(cfgBin()));
// Set default for repo-host-cmd
if (cfgOptionValid(cfgOptRepoHostCmd))
cfgOptionDefaultSet(cfgOptRepoHostCmd, VARSTR(cfgBin()));
// Set default for pg-host-cmd
if (cfgOptionValid(cfgOptPgHostCmd))
cfgOptionDefaultSet(cfgOptPgHostCmd, VARSTR(cfgBin()));
// Protocol timeout should be greater than db timeout // Protocol timeout should be greater than db timeout
if (cfgOptionTest(cfgOptDbTimeout) && cfgOptionTest(cfgOptProtocolTimeout) && if (cfgOptionTest(cfgOptDbTimeout) && cfgOptionTest(cfgOptProtocolTimeout) &&
cfgOptionInt64(cfgOptProtocolTimeout) <= cfgOptionInt64(cfgOptDbTimeout)) cfgOptionInt64(cfgOptProtocolTimeout) <= cfgOptionInt64(cfgOptDbTimeout))
+37 -3
View File
@@ -651,6 +651,16 @@ typedef enum
parseRuleValTime7d, // val/time/enum parseRuleValTime7d, // val/time/enum
} ParseRuleValueTime; } ParseRuleValueTime;
/***********************************************************************************************************************************
Dynamic default values
***********************************************************************************************************************************/
#define PARSE_RULE_DEFAULT_DYNAMIC(value) PARSE_RULE_U32_1(parseRuleDefaultDynamic##value)
typedef enum
{
parseRuleDefaultDynamicBin,
} ParseRuleDefaultDynamic;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Command parse data Command parse data
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@@ -1660,8 +1670,9 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
( // opt/cmd ( // opt/cmd
PARSE_RULE_OPTION_NAME("cmd"), // opt/cmd PARSE_RULE_OPTION_NAME("cmd"), // opt/cmd
PARSE_RULE_OPTION_TYPE(String), // opt/cmd PARSE_RULE_OPTION_TYPE(String), // opt/cmd
PARSE_RULE_OPTION_DEFAULT_TYPE(Dynamic), // opt/cmd
PARSE_RULE_OPTION_RESET(true), // opt/cmd PARSE_RULE_OPTION_RESET(true), // opt/cmd
PARSE_RULE_OPTION_REQUIRED(false), // opt/cmd PARSE_RULE_OPTION_REQUIRED(true), // opt/cmd
PARSE_RULE_OPTION_SECTION(Global), // opt/cmd PARSE_RULE_OPTION_SECTION(Global), // opt/cmd
// opt/cmd // opt/cmd
PARSE_RULE_OPTION_COMMAND_ROLE_MAIN_VALID_LIST // opt/cmd PARSE_RULE_OPTION_COMMAND_ROLE_MAIN_VALID_LIST // opt/cmd
@@ -1697,6 +1708,17 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
PARSE_RULE_OPTION_COMMAND(Backup) // opt/cmd PARSE_RULE_OPTION_COMMAND(Backup) // opt/cmd
PARSE_RULE_OPTION_COMMAND(Restore) // opt/cmd PARSE_RULE_OPTION_COMMAND(Restore) // opt/cmd
PARSE_RULE_OPTION_COMMAND(Verify) // opt/cmd PARSE_RULE_OPTION_COMMAND(Verify) // opt/cmd
), // opt/cmd
// opt/cmd
PARSE_RULE_OPTIONAL // opt/cmd
( // opt/cmd
PARSE_RULE_OPTIONAL_GROUP // opt/cmd
( // opt/cmd
PARSE_RULE_OPTIONAL_DEFAULT // opt/cmd
( // opt/cmd
PARSE_RULE_DEFAULT_DYNAMIC(Bin), // opt/cmd
), // opt/cmd
), // opt/cmd
), // opt/cmd ), // opt/cmd
), // opt/cmd ), // opt/cmd
// ----------------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------------
@@ -3876,8 +3898,9 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
( // opt/pg-host-cmd ( // opt/pg-host-cmd
PARSE_RULE_OPTION_NAME("pg-host-cmd"), // opt/pg-host-cmd PARSE_RULE_OPTION_NAME("pg-host-cmd"), // opt/pg-host-cmd
PARSE_RULE_OPTION_TYPE(String), // opt/pg-host-cmd PARSE_RULE_OPTION_TYPE(String), // opt/pg-host-cmd
PARSE_RULE_OPTION_DEFAULT_TYPE(Dynamic), // opt/pg-host-cmd
PARSE_RULE_OPTION_RESET(true), // opt/pg-host-cmd PARSE_RULE_OPTION_RESET(true), // opt/pg-host-cmd
PARSE_RULE_OPTION_REQUIRED(false), // opt/pg-host-cmd PARSE_RULE_OPTION_REQUIRED(true), // opt/pg-host-cmd
PARSE_RULE_OPTION_SECTION(Stanza), // opt/pg-host-cmd PARSE_RULE_OPTION_SECTION(Stanza), // opt/pg-host-cmd
PARSE_RULE_OPTION_GROUP_ID(Pg), // opt/pg-host-cmd PARSE_RULE_OPTION_GROUP_ID(Pg), // opt/pg-host-cmd
// opt/pg-host-cmd // opt/pg-host-cmd
@@ -3903,6 +3926,11 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
PARSE_RULE_OPTIONAL_DEPEND // opt/pg-host-cmd PARSE_RULE_OPTIONAL_DEPEND // opt/pg-host-cmd
( // opt/pg-host-cmd ( // opt/pg-host-cmd
PARSE_RULE_VAL_OPT(PgHost), // opt/pg-host-cmd PARSE_RULE_VAL_OPT(PgHost), // opt/pg-host-cmd
), // opt/pg-host-cmd
// opt/pg-host-cmd
PARSE_RULE_OPTIONAL_DEFAULT // opt/pg-host-cmd
( // opt/pg-host-cmd
PARSE_RULE_DEFAULT_DYNAMIC(Bin), // opt/pg-host-cmd
), // opt/pg-host-cmd ), // opt/pg-host-cmd
), // opt/pg-host-cmd ), // opt/pg-host-cmd
), // opt/pg-host-cmd ), // opt/pg-host-cmd
@@ -6573,8 +6601,9 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
( // opt/repo-host-cmd ( // opt/repo-host-cmd
PARSE_RULE_OPTION_NAME("repo-host-cmd"), // opt/repo-host-cmd PARSE_RULE_OPTION_NAME("repo-host-cmd"), // opt/repo-host-cmd
PARSE_RULE_OPTION_TYPE(String), // opt/repo-host-cmd PARSE_RULE_OPTION_TYPE(String), // opt/repo-host-cmd
PARSE_RULE_OPTION_DEFAULT_TYPE(Dynamic), // opt/repo-host-cmd
PARSE_RULE_OPTION_RESET(true), // opt/repo-host-cmd PARSE_RULE_OPTION_RESET(true), // opt/repo-host-cmd
PARSE_RULE_OPTION_REQUIRED(false), // opt/repo-host-cmd PARSE_RULE_OPTION_REQUIRED(true), // opt/repo-host-cmd
PARSE_RULE_OPTION_SECTION(Global), // opt/repo-host-cmd PARSE_RULE_OPTION_SECTION(Global), // opt/repo-host-cmd
PARSE_RULE_OPTION_GROUP_ID(Repo), // opt/repo-host-cmd PARSE_RULE_OPTION_GROUP_ID(Repo), // opt/repo-host-cmd
// opt/repo-host-cmd // opt/repo-host-cmd
@@ -6621,6 +6650,11 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
PARSE_RULE_OPTIONAL_DEPEND // opt/repo-host-cmd PARSE_RULE_OPTIONAL_DEPEND // opt/repo-host-cmd
( // opt/repo-host-cmd ( // opt/repo-host-cmd
PARSE_RULE_VAL_OPT(RepoHost), // opt/repo-host-cmd PARSE_RULE_VAL_OPT(RepoHost), // opt/repo-host-cmd
), // opt/repo-host-cmd
// opt/repo-host-cmd
PARSE_RULE_OPTIONAL_DEFAULT // opt/repo-host-cmd
( // opt/repo-host-cmd
PARSE_RULE_DEFAULT_DYNAMIC(Bin), // opt/repo-host-cmd
), // opt/repo-host-cmd ), // opt/repo-host-cmd
), // opt/repo-host-cmd ), // opt/repo-host-cmd
), // opt/repo-host-cmd ), // opt/repo-host-cmd
+58 -26
View File
@@ -35,6 +35,15 @@ typedef enum
cfgSectionStanza, // Command-line or in any config stanza section cfgSectionStanza, // Command-line or in any config stanza section
} ConfigSection; } ConfigSection;
/***********************************************************************************************************************************
Default type enum
***********************************************************************************************************************************/
typedef enum
{
cfgDefaultTypeStatic, // A stored static string
cfgDefaultTypeDynamic, // Determined at runtime
} ConfigDefaultType;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Standard config file name and old default path and name Standard config file name and old default path and name
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@@ -118,6 +127,7 @@ typedef struct ParseRuleOption
{ {
const char *name; // Name const char *name; // Name
unsigned int type : 4; // e.g. string, int, boolean unsigned int type : 4; // e.g. string, int, boolean
unsigned int defaultType : 1; // e.g. static, dynamic
bool boolLike : 1; // Option accepts y/n and can be treated as bool? bool boolLike : 1; // Option accepts y/n and can be treated as bool?
bool beta : 1; // Is the option a beta feature? bool beta : 1; // Is the option a beta feature?
bool negate : 1; // Can the option be negated on the command line? bool negate : 1; // Can the option be negated on the command line?
@@ -163,6 +173,9 @@ typedef enum
#define PARSE_RULE_OPTION_TYPE(typeParam) \ #define PARSE_RULE_OPTION_TYPE(typeParam) \
.type = cfgOptType##typeParam .type = cfgOptType##typeParam
#define PARSE_RULE_OPTION_DEFAULT_TYPE(defaultTypeParam) \
.defaultType = cfgDefaultType##defaultTypeParam
#define PARSE_RULE_OPTION_BOOL_LIKE(boolLikeParam) \ #define PARSE_RULE_OPTION_BOOL_LIKE(boolLikeParam) \
.boolLike = boolLikeParam .boolLike = boolLikeParam
@@ -900,6 +913,7 @@ typedef struct CfgParseOptionalRuleState
size_t allowListSize; size_t allowListSize;
// Default // Default
const String *const defaultDynamicBin; // Binary for dynamic default
const String *defaultRaw; const String *defaultRaw;
ConfigOptionValueType defaultValue; ConfigOptionValueType defaultValue;
@@ -1067,38 +1081,54 @@ cfgParseOptionalRule(
case parseRuleOptionalTypeDefault: case parseRuleOptionalTypeDefault:
{ {
PackRead *const ruleData = pckReadPackReadConstP(optionalRules->pack); PackRead *const ruleData = pckReadPackReadConstP(optionalRules->pack);
pckReadNext(ruleData);
switch (pckReadType(ruleData)) if (ruleOption->defaultType == cfgDefaultTypeDynamic)
{ {
case pckTypeBool: ASSERT(ruleOption->type == cfgOptTypeString);
optionalRules->defaultValue.boolean = pckReadBoolP(ruleData);
optionalRules->defaultRaw = optionalRules->defaultValue.boolean ? Y_STR : N_STR;
break;
default: // No need to check the value until there is more than one
pckReadU32P(ruleData);
optionalRules->defaultValue.string = optionalRules->defaultDynamicBin;
optionalRules->defaultRaw = optionalRules->defaultDynamicBin;
}
else
{
ASSERT(ruleOption->defaultType == cfgDefaultTypeStatic);
pckReadNext(ruleData);
switch (pckReadType(ruleData))
{ {
const unsigned int valueIdx = pckReadU32P(ruleData); case pckTypeBool:
optionalRules->defaultValue.boolean = pckReadBoolP(ruleData);
optionalRules->defaultRaw = optionalRules->defaultValue.boolean ? Y_STR : N_STR;
break;
switch (ruleOption->type) default:
{ {
case cfgOptTypeInteger: const unsigned int valueIdx = pckReadU32P(ruleData);
case cfgOptTypeSize:
case cfgOptTypeTime:
optionalRules->defaultValue.integer = cfgParseOptionValue(ruleOption->type, valueIdx);
break;
case cfgOptTypePath: switch (ruleOption->type)
case cfgOptTypeString: {
optionalRules->defaultValue.string = cfgParseOptionValueStr(ruleOption->type, valueIdx); case cfgOptTypeInteger:
break; case cfgOptTypeSize:
case cfgOptTypeTime:
optionalRules->defaultValue.integer = cfgParseOptionValue(ruleOption->type, valueIdx);
break;
case cfgOptTypeStringId: case cfgOptTypePath:
optionalRules->defaultValue.stringId = parseRuleValueStrId[valueIdx]; case cfgOptTypeString:
break; optionalRules->defaultValue.string = cfgParseOptionValueStr(ruleOption->type, valueIdx);
break;
case cfgOptTypeStringId:
optionalRules->defaultValue.stringId = parseRuleValueStrId[valueIdx];
break;
}
optionalRules->defaultRaw = cfgParseOptionValueStr(ruleOption->type, valueIdx);
} }
optionalRules->defaultRaw = cfgParseOptionValueStr(ruleOption->type, valueIdx);
} }
} }
@@ -1204,21 +1234,23 @@ cfgParseOptionalFilterDepend(PackRead *const filter, const Config *const config,
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/
FN_EXTERN const String * FN_EXTERN const String *
cfgParseOptionDefault(const ConfigCommand commandId, const ConfigOption optionId) cfgParseOptionDefault(const ConfigCommand commandId, const ConfigOption optionId, const String *const defaultDynamicBin)
{ {
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandId); FUNCTION_TEST_PARAM(ENUM, commandId);
FUNCTION_TEST_PARAM(ENUM, optionId); FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_PARAM(STRING, defaultDynamicBin);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
ASSERT(commandId < CFG_COMMAND_TOTAL); ASSERT(commandId < CFG_COMMAND_TOTAL);
ASSERT(optionId < CFG_OPTION_TOTAL); ASSERT(optionId < CFG_OPTION_TOTAL);
ASSERT(defaultDynamicBin != NULL);
const String *result = NULL; const String *result = NULL;
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
CfgParseOptionalRuleState optionalRules = {0}; CfgParseOptionalRuleState optionalRules = {.defaultDynamicBin = defaultDynamicBin};
if (cfgParseOptionalRule(&optionalRules, parseRuleOptionalTypeDefault, commandId, optionId)) if (cfgParseOptionalRule(&optionalRules, parseRuleOptionalTypeDefault, commandId, optionId))
result = optionalRules.defaultRaw; result = optionalRules.defaultRaw;
@@ -2313,7 +2345,7 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
*configOptionValue = (ConfigOptionValue){.negate = parseOptionValue->negate, .reset = parseOptionValue->reset}; *configOptionValue = (ConfigOptionValue){.negate = parseOptionValue->negate, .reset = parseOptionValue->reset};
// Is the option valid? // Is the option valid?
CfgParseOptionalRuleState optionalRules = {0}; CfgParseOptionalRuleState optionalRules = {.defaultDynamicBin = config->bin};
CfgParseOptionalFilterDependResult dependResult = {.valid = true}; CfgParseOptionalFilterDependResult dependResult = {.valid = true};
if (cfgParseOptionalRule(&optionalRules, parseRuleOptionalTypeValid, config->command, optionId)) if (cfgParseOptionalRule(&optionalRules, parseRuleOptionalTypeValid, config->command, optionId))
+1 -1
View File
@@ -108,7 +108,7 @@ typedef struct CfgParseOptionResult
FN_EXTERN CfgParseOptionResult cfgParseOption(const String *const optionName, const CfgParseOptionParam param); FN_EXTERN CfgParseOptionResult cfgParseOption(const String *const optionName, const CfgParseOptionParam param);
// Default value for the option // Default value for the option
FN_EXTERN const String *cfgParseOptionDefault(ConfigCommand commandId, ConfigOption optionId); FN_EXTERN const String *cfgParseOptionDefault(ConfigCommand commandId, ConfigOption optionId, const String *defaultDynamicBin);
// Option name from id // Option name from id
FN_EXTERN const char *cfgParseOptionName(ConfigOption optionId); FN_EXTERN const char *cfgParseOptionName(ConfigOption optionId);
+1 -1
View File
@@ -531,7 +531,7 @@ protocolRemoteParam(const ProtocolStorageType protocolStorageType, const unsigne
{ {
remove = remove =
!cfgParseOptionRequired(cfgCommand(), optionId) || !cfgParseOptionRequired(cfgCommand(), optionId) ||
cfgParseOptionDefault(cfgCommand(), optionId) != NULL; cfgParseOptionDefault(cfgCommand(), optionId, cfgBin()) != NULL;
} }
// Move pg options to host index 0 (key 1) so they will be in the default index on the remote host // Move pg options to host index 0 (key 1) so they will be in the default index on the remote host
else else
+1
View File
@@ -192,6 +192,7 @@ option:
# Options that are not used but must be present for modules to compile. All must have a default or not be required. # Options that are not used but must be present for modules to compile. All must have a default or not be required.
#--------------------------------------------------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------------------------------------------------
beta: {type: boolean, default: false, command: {noop: {}}} beta: {type: boolean, default: false, command: {noop: {}}}
cmd: {type: string, default-type: dynamic, default: bin, command: {noop: {}}}
compress-level-network: {type: string, required: false, command: {noop: {}}} compress-level-network: {type: string, required: false, command: {noop: {}}}
config: { config: {
type: string, internal: true, default-type: literal, default: CFGOPTDEF_CONFIG_PATH "/" PROJECT_CONFIG_FILE, negate: true} type: string, internal: true, default-type: literal, default: CFGOPTDEF_CONFIG_PATH "/" PROJECT_CONFIG_FILE, negate: true}
+1
View File
@@ -7,6 +7,7 @@
<operation-general> <operation-general>
<option-list> <option-list>
<option id="beta"><summary></summary><text><p></p></text></option> <option id="beta"><summary></summary><text><p></p></text></option>
<option id="cmd"><summary></summary><text><p></p></text></option>
<option id="config"><summary></summary><text><p></p></text></option> <option id="config"><summary></summary><text><p></p></text></option>
<option id="config-path"><summary></summary><text><p></p></text></option> <option id="config-path"><summary></summary><text><p></p></text></option>
<option id="config-include-path"><summary></summary><text><p></p></text></option> <option id="config-include-path"><summary></summary><text><p></p></text></option>
+59 -1
View File
@@ -299,6 +299,14 @@ testRun(void)
" command-role:\n" " command-role:\n"
" main: {}\n" " main: {}\n"
"\n" "\n"
" cmd:\n"
" section: global\n"
" type: string\n"
" default-type: dynamic\n"
" default: bin\n"
" command:\n"
" backup: {}\n"
"\n"
" compress-network:\n" " compress-network:\n"
" section: global\n" " section: global\n"
" type: string-id\n" " type: string-id\n"
@@ -354,6 +362,7 @@ testRun(void)
" config-include:\n" " config-include:\n"
" section: global\n" " section: global\n"
" type: path\n" " type: path\n"
" default-type: quote\n"
" default: /include\n" " default: /include\n"
" command-role:\n" " command-role:\n"
" main: {}\n" " main: {}\n"
@@ -503,6 +512,7 @@ testRun(void)
"#define CFGOPT_BACKUP_STANDBY \"backup-standby\"\n" "#define CFGOPT_BACKUP_STANDBY \"backup-standby\"\n"
"#define CFGOPT_BOOL_LIKE \"bool-like\"\n" "#define CFGOPT_BOOL_LIKE \"bool-like\"\n"
"#define CFGOPT_BUFFER_SIZE \"buffer-size\"\n" "#define CFGOPT_BUFFER_SIZE \"buffer-size\"\n"
"#define CFGOPT_CMD \"cmd\"\n"
"#define CFGOPT_COMPRESS_LEVEL \"compress-level\"\n" "#define CFGOPT_COMPRESS_LEVEL \"compress-level\"\n"
"#define CFGOPT_COMPRESS_LEVEL_NETWORK \"compress-level-network\"\n" "#define CFGOPT_COMPRESS_LEVEL_NETWORK \"compress-level-network\"\n"
"#define CFGOPT_COMPRESS_NETWORK \"compress-network\"\n" "#define CFGOPT_COMPRESS_NETWORK \"compress-network\"\n"
@@ -515,7 +525,7 @@ testRun(void)
"#define CFGOPT_STANZA \"stanza\"\n" "#define CFGOPT_STANZA \"stanza\"\n"
"#define CFGOPT_TIMEOUT \"timeout\"\n" "#define CFGOPT_TIMEOUT \"timeout\"\n"
"\n" "\n"
"#define CFG_OPTION_TOTAL 16\n" "#define CFG_OPTION_TOTAL 17\n"
"\n" "\n"
COMMENT_BLOCK_BEGIN "\n" COMMENT_BLOCK_BEGIN "\n"
"Option value constants\n" "Option value constants\n"
@@ -576,6 +586,7 @@ testRun(void)
" cfgOptBackupStandby,\n" " cfgOptBackupStandby,\n"
" cfgOptBoolLike,\n" " cfgOptBoolLike,\n"
" cfgOptBufferSize,\n" " cfgOptBufferSize,\n"
" cfgOptCmd,\n"
" cfgOptCompressLevel,\n" " cfgOptCompressLevel,\n"
" cfgOptCompressLevelNetwork,\n" " cfgOptCompressLevelNetwork,\n"
" cfgOptCompressNetwork,\n" " cfgOptCompressNetwork,\n"
@@ -785,6 +796,16 @@ testRun(void)
"} ParseRuleValueTime;\n" "} ParseRuleValueTime;\n"
"\n" "\n"
COMMENT_BLOCK_BEGIN "\n" COMMENT_BLOCK_BEGIN "\n"
"Dynamic default values\n"
COMMENT_BLOCK_END "\n"
"#define PARSE_RULE_DEFAULT_DYNAMIC(value) PARSE_RULE_U32_1(parseRuleDefaultDynamic##value)\n"
"\n"
"typedef enum\n"
"{\n"
" parseRuleDefaultDynamicBin,\n"
"} ParseRuleDefaultDynamic;\n"
"\n"
COMMENT_BLOCK_BEGIN "\n"
"Command parse data\n" "Command parse data\n"
COMMENT_BLOCK_END "\n" COMMENT_BLOCK_END "\n"
"#define PARSE_RULE_VAL_CMD(value) PARSE_RULE_U32_1(cfgCmd##value)\n" "#define PARSE_RULE_VAL_CMD(value) PARSE_RULE_U32_1(cfgCmd##value)\n"
@@ -992,6 +1013,42 @@ testRun(void)
COMMENT_SEPARATOR "\n" COMMENT_SEPARATOR "\n"
" PARSE_RULE_OPTION\n" " PARSE_RULE_OPTION\n"
" (\n" " (\n"
" PARSE_RULE_OPTION_NAME(\"cmd\"),\n"
" PARSE_RULE_OPTION_TYPE(String),\n"
" PARSE_RULE_OPTION_DEFAULT_TYPE(Dynamic),\n"
" PARSE_RULE_OPTION_RESET(true),\n"
" PARSE_RULE_OPTION_REQUIRED(true),\n"
" PARSE_RULE_OPTION_SECTION(Global),\n"
"\n"
" PARSE_RULE_OPTION_COMMAND_ROLE_MAIN_VALID_LIST\n"
" (\n"
" PARSE_RULE_OPTION_COMMAND(Backup)\n"
" ),\n"
"\n"
" PARSE_RULE_OPTION_COMMAND_ROLE_LOCAL_VALID_LIST\n"
" (\n"
" PARSE_RULE_OPTION_COMMAND(Backup)\n"
" ),\n"
"\n"
" PARSE_RULE_OPTION_COMMAND_ROLE_REMOTE_VALID_LIST\n"
" (\n"
" PARSE_RULE_OPTION_COMMAND(Backup)\n"
" ),\n"
"\n"
" PARSE_RULE_OPTIONAL\n"
" (\n"
" PARSE_RULE_OPTIONAL_GROUP\n"
" (\n"
" PARSE_RULE_OPTIONAL_DEFAULT\n"
" (\n"
" PARSE_RULE_DEFAULT_DYNAMIC(Bin),\n"
" ),\n"
" ),\n"
" ),\n"
" ),\n"
COMMENT_SEPARATOR "\n"
" PARSE_RULE_OPTION\n"
" (\n"
" PARSE_RULE_OPTION_NAME(\"compress-level\"),\n" " PARSE_RULE_OPTION_NAME(\"compress-level\"),\n"
" PARSE_RULE_OPTION_TYPE(Integer),\n" " PARSE_RULE_OPTION_TYPE(Integer),\n"
" PARSE_RULE_OPTION_RESET(true),\n" " PARSE_RULE_OPTION_RESET(true),\n"
@@ -1701,6 +1758,7 @@ testRun(void)
" cfgOptStanza,\n" " cfgOptStanza,\n"
" cfgOptBoolLike,\n" " cfgOptBoolLike,\n"
" cfgOptBufferSize,\n" " cfgOptBufferSize,\n"
" cfgOptCmd,\n"
" cfgOptCompressNetwork,\n" " cfgOptCompressNetwork,\n"
" cfgOptConfig,\n" " cfgOptConfig,\n"
" cfgOptConfigInclude,\n" " cfgOptConfigInclude,\n"
-33
View File
@@ -135,39 +135,6 @@ testRun(void)
hrnCfgEnvKeyRemoveRaw(cfgOptRepoS3Key, 3); hrnCfgEnvKeyRemoveRaw(cfgOptRepoS3Key, 3);
hrnCfgEnvKeyRemoveRaw(cfgOptRepoS3KeySecret, 3); hrnCfgEnvKeyRemoveRaw(cfgOptRepoS3KeySecret, 3);
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("repo-host-cmd is defaulted when null");
argList = strLstNew();
hrnCfgArgRawZ(argList, cfgOptStanza, "test");
hrnCfgArgRawZ(argList, cfgOptPgPath, "/pg1");
HRN_CFG_LOAD(cfgCmdCheck, argList);
cfgOptionIdxSet(cfgOptRepoHost, 0, cfgSourceParam, varNewStrZ("repo-host"));
TEST_RESULT_VOID(cfgLoadUpdateOption(), "repo remote command is updated");
TEST_RESULT_STR_Z(cfgOptionIdxStr(cfgOptRepoHostCmd, 0), testProjectExe(), "check repo1-host-cmd");
cfgOptionIdxSet(cfgOptRepoHostCmd, 0, cfgSourceParam, VARSTRDEF("/other"));
TEST_RESULT_VOID(cfgLoadUpdateOption(), "repo remote command was already set");
TEST_RESULT_STR_Z(cfgOptionIdxStr(cfgOptRepoHostCmd, 0), "/other", "check repo1-host-cmd");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("pg-host-cmd is defaulted when null");
argList = strLstNew();
hrnCfgArgRawZ(argList, cfgOptStanza, "test");
hrnCfgArgKeyRawZ(argList, cfgOptPgPath, 1, "/pg1");
hrnCfgArgKeyRawZ(argList, cfgOptPgHost, 1, "pg1");
hrnCfgArgKeyRawZ(argList, cfgOptPgPath, 99, "/pg99");
hrnCfgArgKeyRawZ(argList, cfgOptPgHost, 99, "pg99");
hrnCfgArgKeyRawZ(argList, cfgOptPgHostCmd, 99, "pg99-exe");
HRN_CFG_LOAD(cfgCmdCheck, argList);
TEST_RESULT_STR_Z(cfgOptionIdxStr(cfgOptPgHostCmd, 0), testProjectExe(), "check pg1-host-cmd");
TEST_RESULT_STR_Z(cfgOptionIdxStr(cfgOptPgHostCmd, 1), "pg99-exe", "check pg99-host-cmd");
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("db-timeout set but not protocol timeout"); TEST_TITLE("db-timeout set but not protocol timeout");
+3 -1
View File
@@ -1965,10 +1965,12 @@ testRun(void)
TEST_RESULT_STR_Z(cfgOptionDisplay(cfgOptPgPort), "5432", "pg-port display is 5432"); TEST_RESULT_STR_Z(cfgOptionDisplay(cfgOptPgPort), "5432", "pg-port display is 5432");
TEST_RESULT_STR_Z(cfgOptionDefault(cfgOptDbTimeout), "30m", "db-timeout default is 30m"); TEST_RESULT_STR_Z(cfgOptionDefault(cfgOptDbTimeout), "30m", "db-timeout default is 30m");
TEST_RESULT_VOID(cfgOptionDefaultSet(cfgOptPgSocketPath, VARSTRDEF("/default")), "set pg-socket-path default"); TEST_RESULT_VOID(
cfgOptionIdxSet(cfgOptPgSocketPath, 1, cfgSourceDefault, VARSTRDEF("/default")), "set pg-socket-path default");
TEST_RESULT_STR_Z(cfgOptionIdxStr(cfgOptPgSocketPath, 0), "@socket", "pg1-socket-path unchanged"); TEST_RESULT_STR_Z(cfgOptionIdxStr(cfgOptPgSocketPath, 0), "@socket", "pg1-socket-path unchanged");
TEST_RESULT_STR_Z(cfgOptionIdxStr(cfgOptPgSocketPath, 1), "/default", "pg2-socket-path is new default"); TEST_RESULT_STR_Z(cfgOptionIdxStr(cfgOptPgSocketPath, 1), "/default", "pg2-socket-path is new default");
TEST_RESULT_STR_Z(cfgOptionIdxDisplay(cfgOptPgSocketPath, 1), "/default", "pg2-socket-path display"); TEST_RESULT_STR_Z(cfgOptionIdxDisplay(cfgOptPgSocketPath, 1), "/default", "pg2-socket-path display");
TEST_RESULT_UINT(cfgOptionIdxTotal(cfgOptPgSocketPath), 3, "pg-socket-path index total");
TEST_ERROR(cfgOptionDisplay(cfgOptTarget), AssertError, "option 'target' is not valid for the current command"); TEST_ERROR(cfgOptionDisplay(cfgOptTarget), AssertError, "option 'target' is not valid for the current command");
TEST_ERROR(cfgOptionLst(cfgOptDbInclude), AssertError, "option 'db-include' is not valid for the current command"); TEST_ERROR(cfgOptionLst(cfgOptDbInclude), AssertError, "option 'db-include' is not valid for the current command");
+22
View File
@@ -77,6 +77,14 @@ testRun(void)
" default: 1024\n" " default: 1024\n"
" allow-list: [512, 1024, 2048, 4096]\n" " allow-list: [512, 1024, 2048, 4096]\n"
"\n" "\n"
" cmd:\n"
" section: global\n"
" type: string\n"
" default-type: dynamic\n"
" default: bin\n"
" command:\n"
" backup: {}\n"
"\n"
" internal:\n" " internal:\n"
" section: global\n" " section: global\n"
" internal: true\n" " internal: true\n"
@@ -189,6 +197,12 @@ testRun(void)
" <text><p>Backup command description.</p></text>\n" " <text><p>Backup command description.</p></text>\n"
"\n" "\n"
" <option-list>\n" " <option-list>\n"
" <option id=\"cmd\" name=\"Cmd\">\n"
" <summary>Cmd option command backup summary.</summary>\n"
" <text><p>Cmd option command backup description.</p></text>\n"
" <example>pgbackrest</example>"
" </option>\n"
"\n"
" <option id=\"force\" name=\"Force Backup\">\n" " <option id=\"force\" name=\"Force Backup\">\n"
" <summary>Force option command backup summary.</summary>\n" " <summary>Force option command backup summary.</summary>\n"
" <text><p>Force option command backup description.</p></text>\n" " <text><p>Force option command backup description.</p></text>\n"
@@ -287,6 +301,13 @@ testRun(void)
"<p>Backup command description.</p>" "<p>Backup command description.</p>"
"<section id=\"category-command\" toc=\"n\">" "<section id=\"category-command\" toc=\"n\">"
"<title>Command Options</title>" "<title>Command Options</title>"
"<section id=\"option-cmd\">"
"<title>Cmd Option (<id>--cmd</id>)</title>"
"<p>Cmd option command backup summary.</p>"
"<p>Cmd option command backup description.</p>"
"<code-block>default: [path of executed pgbackrest binary]\n"
"example: --cmd=pgbackrest</code-block>"
"</section>"
"<section id=\"option-force\">" "<section id=\"option-force\">"
"<title>Force Backup Option (<id>--force</id>)</title>" "<title>Force Backup Option (<id>--force</id>)</title>"
"<p>Force option command backup summary.</p>" "<p>Force option command backup summary.</p>"
@@ -370,6 +391,7 @@ testRun(void)
"\n" "\n"
"OPTIONS\n" "OPTIONS\n"
" Backup Options:\n" " Backup Options:\n"
" --cmd Cmd option command backup summary.\n"
" --force Force option command backup summary.\n" " --force Force option command backup summary.\n"
" --repo-compress-level Repo compress level option command backup summary.\n" " --repo-compress-level Repo compress level option command backup summary.\n"
"\n" "\n"