1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-03-03 14:52:21 +02:00

631 lines
23 KiB
Perl
Raw Normal View History

2017-11-28 21:44:05 -05:00
####################################################################################################################################
# Auto-Generate Option Definition for Parsing with getopt_long().
####################################################################################################################################
package pgBackRestBuild::Config::BuildParse;
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
use English '-no_match_vars';
use Cwd qw(abs_path);
use Exporter qw(import);
our @EXPORT = qw();
use File::Basename qw(dirname);
use Storable qw(dclone);
use pgBackRestDoc::Common::Log;
use pgBackRestDoc::Common::String;
use pgBackRestDoc::ProjectInfo;
2017-11-28 21:44:05 -05:00
use pgBackRestBuild::Build::Common;
use pgBackRestBuild::Config::Build;
use pgBackRestBuild::Config::Data;
####################################################################################################################################
# Constants
####################################################################################################################################
use constant BLDLCL_FILE_DEFINE => 'parse';
use constant BLDLCL_ENUM_OPTION_TYPE => '01-enumOptionType';
use constant BLDLCL_DATA_COMMAND => '01-dataCommand';
use constant BLDLCL_DATA_OPTION_GROUP => '01-dataOptionGroup';
use constant BLDLCL_DATA_OPTION => '02-dataOption';
use constant BLDLCL_DATA_OPTION_GETOPT => '03-dataOptionGetOpt';
use constant BLDLCL_DATA_OPTION_RESOLVE => '04-dataOptionResolve';
2017-11-28 21:44:05 -05:00
####################################################################################################################################
# Definitions for constants and data to build
####################################################################################################################################
my $strSummary = 'Config Parse Rules';
2017-11-28 21:44:05 -05:00
my $rhBuild =
{
&BLD_FILE =>
{
&BLDLCL_FILE_DEFINE =>
{
&BLD_SUMMARY => $strSummary,
&BLD_ENUM =>
{
&BLDLCL_ENUM_OPTION_TYPE =>
{
&BLD_SUMMARY => 'Option type',
&BLD_NAME => 'ConfigOptionType',
},
},
2017-11-28 21:44:05 -05:00
&BLD_DATA =>
{
&BLDLCL_DATA_COMMAND =>
{
&BLD_SUMMARY => 'Command parse data',
},
&BLDLCL_DATA_OPTION_GROUP =>
{
&BLD_SUMMARY => 'Option group parse data',
},
2017-11-28 21:44:05 -05:00
&BLDLCL_DATA_OPTION =>
{
&BLD_SUMMARY => 'Option parse data',
},
&BLDLCL_DATA_OPTION_GETOPT =>
{
&BLD_SUMMARY => 'Option data for getopt_long()',
},
&BLDLCL_DATA_OPTION_RESOLVE =>
{
&BLD_SUMMARY => 'Order for option parse resolution',
},
2017-11-28 21:44:05 -05:00
},
},
},
};
####################################################################################################################################
# Generate enum names
####################################################################################################################################
sub buildConfigDefineOptionTypeEnum
{
return bldEnum('cfgOptType', shift);
}
push @EXPORT, qw(buildConfigDefineOptionTypeEnum);
sub buildConfigCommandRoleEnum
{
return bldEnum('cfgCmdRole', shift);
}
####################################################################################################################################
# Helper functions for building optional option data
####################################################################################################################################
sub renderAllowList
{
my $ryAllowList = shift;
my $bCommandIndent = shift;
my $strIndent = $bCommandIndent ? ' ' : '';
return
"${strIndent} PARSE_RULE_OPTION_OPTIONAL_ALLOW_LIST\n" .
"${strIndent} (\n" .
"${strIndent} " . join(",\n${strIndent} ", bldQuoteList($ryAllowList)) .
"\n" .
"${strIndent} ),\n";
}
sub renderDepend
{
my $rhDepend = shift;
my $bCommandIndent = shift;
my $strIndent = $bCommandIndent ? ' ' : '';
my $strDependOption = $rhDepend->{&CFGDEF_DEPEND_OPTION};
my $ryDependList = $rhDepend->{&CFGDEF_DEPEND_LIST};
if (defined($ryDependList))
{
my @stryQuoteList;
foreach my $strItem (@{$ryDependList})
{
push(@stryQuoteList, "\"${strItem}\"");
}
return
"${strIndent} PARSE_RULE_OPTION_OPTIONAL_DEPEND_LIST\n" .
"${strIndent} (\n" .
"${strIndent} " . buildConfigOptionEnum($strDependOption) . ",\n" .
"${strIndent} " . join(",\n${strIndent} ", bldQuoteList($ryDependList)) .
"\n" .
"${strIndent} ),\n";
}
return
"${strIndent} PARSE_RULE_OPTION_OPTIONAL_DEPEND(" . buildConfigOptionEnum($strDependOption) . "),\n";
}
sub renderOptional
{
my $rhOptional = shift;
my $bCommand = shift;
my $strCommand = shift;
my $strOption = shift;
my $strIndent = $bCommand ? ' ' : '';
my $strBuildSourceOptional;
my $bSingleLine = false;
if (defined($rhOptional->{&CFGDEF_ALLOW_LIST}))
{
$strBuildSourceOptional .=
(defined($strBuildSourceOptional) && !$bSingleLine ? "\n" : '') .
renderAllowList($rhOptional->{&CFGDEF_ALLOW_LIST}, $bCommand);
$bSingleLine = false;
}
if (defined($rhOptional->{&CFGDEF_ALLOW_RANGE}))
{
my @fyRange = @{$rhOptional->{&CFGDEF_ALLOW_RANGE}};
my $iMultiplier = $rhOptional->{&CFGDEF_TYPE} eq CFGDEF_TYPE_TIME ? 1000 : 1;
$strBuildSourceOptional =
(defined($strBuildSourceOptional) && !$bSingleLine ? "\n" : '') .
"${strIndent} PARSE_RULE_OPTION_OPTIONAL_ALLOW_RANGE(" . ($fyRange[0] * $iMultiplier) . ', ' .
($fyRange[1] * $iMultiplier) . "),\n";
$bSingleLine = true;
}
if (defined($rhOptional->{&CFGDEF_DEPEND}))
{
$strBuildSourceOptional .=
(defined($strBuildSourceOptional) && !$bSingleLine ? "\n" : '') .
renderDepend($rhOptional->{&CFGDEF_DEPEND}, $bCommand);
$bSingleLine = defined($rhOptional->{&CFGDEF_DEPEND}{&CFGDEF_DEPEND_LIST}) ? false : true;
}
if (defined($rhOptional->{&CFGDEF_DEFAULT}))
{
$strBuildSourceOptional .=
(defined($strBuildSourceOptional) && !$bSingleLine ? "\n" : '') .
"${strIndent} PARSE_RULE_OPTION_OPTIONAL_DEFAULT(" .
($rhOptional->{&CFGDEF_DEFAULT_LITERAL} ? '' : '"') .
(defined($rhOptional->{&CFGDEF_TYPE}) && $rhOptional->{&CFGDEF_TYPE} eq CFGDEF_TYPE_TIME ?
$rhOptional->{&CFGDEF_DEFAULT} * 1000 : $rhOptional->{&CFGDEF_DEFAULT}) .
($rhOptional->{&CFGDEF_DEFAULT_LITERAL} ? '' : '"') .
"),\n";
$bSingleLine = true;
}
if ($bCommand && defined($rhOptional->{&CFGDEF_REQUIRED}))
{
$strBuildSourceOptional .=
(defined($strBuildSourceOptional) && !$bSingleLine ? "\n" : '') .
"${strIndent} PARSE_RULE_OPTION_OPTIONAL_REQUIRED(" .
($rhOptional->{&CFGDEF_REQUIRED} ? 'true' : 'false') . "),\n";
$bSingleLine = true;
}
return $strBuildSourceOptional;
}
2017-11-28 21:44:05 -05:00
####################################################################################################################################
# Build configuration constants and data
####################################################################################################################################
sub buildConfigParse
{
# Build option type enum
# ------------------------------------------------------------------------------------------------------------------------------
my $rhEnum = $rhBuild->{&BLD_FILE}{&BLDLCL_FILE_DEFINE}{&BLD_ENUM}{&BLDLCL_ENUM_OPTION_TYPE};
foreach my $strOptionType (cfgDefineOptionTypeList())
{
# Build C enum
my $strOptionTypeEnum = buildConfigDefineOptionTypeEnum($strOptionType);
push(@{$rhEnum->{&BLD_LIST}}, $strOptionTypeEnum);
};
# Build command parse data
# ------------------------------------------------------------------------------------------------------------------------------
my $rhCommandDefine = cfgDefineCommand();
2017-11-28 21:44:05 -05:00
my $strBuildSource =
"static const ParseRuleCommand parseRuleCommand[CFG_COMMAND_TOTAL] =\n" .
"{";
foreach my $strCommand (sort(keys(%{$rhCommandDefine})))
{
my $rhCommand = $rhCommandDefine->{$strCommand};
# Build command data
$strBuildSource .=
"\n" .
" //" . (qw{-} x 126) . "\n" .
" PARSE_RULE_COMMAND\n" .
" (\n" .
" PARSE_RULE_COMMAND_NAME(\"${strCommand}\"),\n";
if ($rhCommand->{&CFGDEF_PARAMETER_ALLOWED})
{
$strBuildSource .=
" PARSE_RULE_COMMAND_PARAMETER_ALLOWED(true),\n";
}
$strBuildSource .=
"\n" .
" PARSE_RULE_COMMAND_ROLE_VALID_LIST\n" .
" (\n";
foreach my $strCommandRole (sort(keys(%{$rhCommand->{&CFGDEF_COMMAND_ROLE}})))
{
$strBuildSource .=
" PARSE_RULE_COMMAND_ROLE(" . buildConfigCommandRoleEnum($strCommandRole) . ")\n";
}
$strBuildSource .=
" ),\n";
$strBuildSource .=
" ),\n";
};
$strBuildSource .=
"};\n";
$rhBuild->{&BLD_FILE}{&BLDLCL_FILE_DEFINE}{&BLD_DATA}{&BLDLCL_DATA_COMMAND}{&BLD_SOURCE} = $strBuildSource;
# Build option group parse data
# ------------------------------------------------------------------------------------------------------------------------------
my $rhOptionGroupDefine = cfgDefineOptionGroup();
$strBuildSource =
"static const ParseRuleOptionGroup parseRuleOptionGroup[CFG_OPTION_GROUP_TOTAL] =\n" .
"{";
foreach my $strGroup (sort(keys(%{$rhOptionGroupDefine})))
{
$strBuildSource .=
"\n" .
" //" . (qw{-} x 126) . "\n" .
" PARSE_RULE_OPTION_GROUP\n" .
" (\n" .
" PARSE_RULE_OPTION_GROUP_NAME(\"" . $strGroup . "\"),\n" .
" ),\n";
}
$strBuildSource .=
"};\n";
$rhBuild->{&BLD_FILE}{&BLDLCL_FILE_DEFINE}{&BLD_DATA}{&BLDLCL_DATA_OPTION_GROUP}{&BLD_SOURCE} = $strBuildSource;
# Build option parse data
# ------------------------------------------------------------------------------------------------------------------------------
my $rhConfigDefine = cfgDefine();
$strBuildSource =
"static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =\n" .
"{";
foreach my $strOption (sort(keys(%{$rhConfigDefine})))
{
my $rhOption = $rhConfigDefine->{$strOption};
$strBuildSource .=
"\n" .
" // " . (qw{-} x 125) . "\n" .
" PARSE_RULE_OPTION\n" .
" (\n" .
" PARSE_RULE_OPTION_NAME(\"${strOption}\"),\n" .
" PARSE_RULE_OPTION_TYPE(" . buildConfigDefineOptionTypeEnum($rhOption->{&CFGDEF_TYPE}) . "),\n" .
" PARSE_RULE_OPTION_REQUIRED(" . ($rhOption->{&CFGDEF_REQUIRED} ? 'true' : 'false') . "),\n" .
" PARSE_RULE_OPTION_SECTION(cfgSection" .
(defined($rhOption->{&CFGDEF_SECTION}) ? ucfirst($rhOption->{&CFGDEF_SECTION}) : 'CommandLine') .
"),\n";
if ($rhOption->{&CFGDEF_SECURE})
{
$strBuildSource .=
" PARSE_RULE_OPTION_SECURE(true),\n";
}
if ($rhOption->{&CFGDEF_TYPE} eq CFGDEF_TYPE_HASH || $rhOption->{&CFGDEF_TYPE} eq CFGDEF_TYPE_LIST)
{
$strBuildSource .=
" PARSE_RULE_OPTION_MULTI(true),\n";
}
# Build group info
# --------------------------------------------------------------------------------------------------------------------------
if ($rhOption->{&CFGDEF_GROUP})
{
$strBuildSource .=
" PARSE_RULE_OPTION_GROUP_MEMBER(true),\n" .
" PARSE_RULE_OPTION_GROUP_ID(" . buildConfigOptionGroupEnum($rhOption->{&CFGDEF_GROUP}) . "),\n";
}
# Build command role valid lists
#---------------------------------------------------------------------------------------------------------------------------
my $strBuildSourceSub = "";
foreach my $strCommandRole (CFGCMD_ROLE_MAIN, CFGCMD_ROLE_ASYNC, CFGCMD_ROLE_LOCAL, CFGCMD_ROLE_REMOTE)
{
$strBuildSourceSub = "";
foreach my $strCommand (cfgDefineCommandList())
{
if (defined($rhOption->{&CFGDEF_COMMAND}{$strCommand}))
{
if (defined($rhOption->{&CFGDEF_COMMAND}{$strCommand}{&CFGDEF_COMMAND_ROLE}{$strCommandRole}))
{
$strBuildSourceSub .=
" PARSE_RULE_OPTION_COMMAND(" . buildConfigCommandEnum($strCommand) . ")\n";
}
}
}
if ($strBuildSourceSub ne "")
{
$strBuildSource .=
"\n" .
" PARSE_RULE_OPTION_COMMAND_ROLE_" . uc($strCommandRole) . "_VALID_LIST\n" .
" (\n" .
$strBuildSourceSub .
" ),\n";
}
}
# Render optional data and command overrides
# --------------------------------------------------------------------------------------------------------------------------
my $strBuildSourceOptional = renderOptional($rhOption, false);
foreach my $strCommand (cfgDefineCommandList())
{
my $strBuildSourceOptionalCommand;
my $rhCommand = $rhOption->{&CFGDEF_COMMAND}{$strCommand};
if (defined($rhCommand))
{
$strBuildSourceOptionalCommand = renderOptional($rhCommand, true, $strCommand, $strOption);
if (defined($strBuildSourceOptionalCommand))
{
$strBuildSourceOptional .=
(defined($strBuildSourceOptional) ? "\n" : '') .
" PARSE_RULE_OPTION_OPTIONAL_COMMAND_OVERRIDE\n" .
" (\n" .
" PARSE_RULE_OPTION_OPTIONAL_COMMAND(" . buildConfigCommandEnum($strCommand) . "),\n" .
"\n" .
$strBuildSourceOptionalCommand .
" )\n";
}
}
}
if (defined($strBuildSourceOptional))
{
$strBuildSource .=
"\n" .
" PARSE_RULE_OPTION_OPTIONAL_LIST\n" .
" (\n" .
$strBuildSourceOptional .
" ),\n";
}
$strBuildSource .=
" ),\n";
}
$strBuildSource .=
"};\n";
$rhBuild->{&BLD_FILE}{&BLDLCL_FILE_DEFINE}{&BLD_DATA}{&BLDLCL_DATA_OPTION}{&BLD_SOURCE} = $strBuildSource;
# Build option list for getopt_long()
#-------------------------------------------------------------------------------------------------------------------------------
$strBuildSource =
2017-11-28 21:44:05 -05:00
"static const struct option optionList[] =\n" .
"{";
2017-11-28 21:44:05 -05:00
foreach my $strOption (sort(keys(%{$rhConfigDefine})))
{
my $rhOption = $rhConfigDefine->{$strOption};
my $strOptionEnum = buildConfigOptionEnum($strOption);
my $strOptionArg = ($rhOption->{&CFGDEF_TYPE} ne CFGDEF_TYPE_BOOLEAN ? " .has_arg = required_argument,\n" : '');
my $strOptionPrefix = $rhConfigDefine->{$strOption}{&CFGDEF_PREFIX};
my @stryOptionName = ($strOption);
if (defined($rhOption->{&CFGDEF_DEPRECATE}))
{
foreach my $strOptionNameAlt (sort(keys(%{$rhOption->{&CFGDEF_DEPRECATE}})))
{
push(@stryOptionName, $strOptionNameAlt);
}
}
$strBuildSource .=
"\n" .
" // ${strOption} option" . (@stryOptionName > 1 ? ' and deprecations' : '') . "\n" .
" // " . (qw{-} x 125) . "\n";
for (my $iOptionIdx = 1; $iOptionIdx <= $rhOption->{&CFGDEF_INDEX_TOTAL}; $iOptionIdx++)
2017-11-28 21:44:05 -05:00
{
for (my $iOptionNameIdx = 0; $iOptionNameIdx < @stryOptionName; $iOptionNameIdx++)
{
my $strOptionName = $stryOptionName[$iOptionNameIdx];
my $rhNameAlt = $rhOption->{&CFGDEF_DEPRECATE}{$strOptionName};
2017-11-28 21:44:05 -05:00
# Skip alt name if it is not valid for this option index
if ($iOptionNameIdx > 0 && defined($rhNameAlt->{&CFGDEF_INDEX}) && $rhNameAlt->{&CFGDEF_INDEX} != $iOptionIdx)
{
next;
}
2017-11-28 21:44:05 -05:00
# Generate output name
my $strOptionNameOut = $strOptionName;
my $strOptionConst;
if (defined($strOptionPrefix))
{
if ($iOptionNameIdx == 0)
{
$strOptionNameOut =
"${strOptionPrefix}${iOptionIdx}-" . substr($strOptionName, length($strOptionPrefix) + 1);
}
else
{
$strOptionNameOut =~ s/\?/$iOptionIdx/g;
}
}
# Generate option value used for parsing (offset is added so options don't conflict with getopt_long return values)
my $strOptionFlag = 'PARSE_OPTION_FLAG |';
# Build option constant name if this is the current name for the option
if ($iOptionNameIdx == 0)
{
if (!$rhConfigDefine->{$strOption}{&CFGDEF_GROUP})
{
$strOptionConst = "CFGOPT_" . uc($strOptionNameOut);
$strOptionConst =~ s/\-/_/g;
}
}
# Else use bare string and mark as deprecated
else
{
$strOptionFlag .= ' PARSE_DEPRECATE_FLAG |';
}
2017-11-28 21:44:05 -05:00
my $strOptionVal =
($rhOption->{&CFGDEF_GROUP} ? "(" . ($iOptionIdx - 1) . " << PARSE_KEY_IDX_SHIFT) | " : '') . $strOptionEnum;
2017-11-28 21:44:05 -05:00
# Add option
2017-11-28 21:44:05 -05:00
$strBuildSource .=
" {\n" .
" .name = \"${strOptionNameOut}\",\n" .
$strOptionArg .
" .val = ${strOptionFlag} ${strOptionVal},\n" .
2017-11-28 21:44:05 -05:00
" },\n";
# Add negation when defined
if ($rhOption->{&CFGDEF_NEGATE} &&
!($iOptionNameIdx > 0 && defined($rhNameAlt->{&CFGDEF_NEGATE}) && !$rhNameAlt->{&CFGDEF_NEGATE}))
{
$strBuildSource .=
" {\n" .
" .name = \"no-${strOptionNameOut}\",\n" .
" .val = ${strOptionFlag} PARSE_NEGATE_FLAG | ${strOptionVal},\n" .
" },\n";
}
# Add reset when defined
if ($rhOption->{&CFGDEF_RESET} &&
!($iOptionNameIdx > 0 && defined($rhNameAlt->{&CFGDEF_RESET}) && !$rhNameAlt->{&CFGDEF_RESET}))
{
$strBuildSource .=
" {\n" .
" .name = \"reset-${strOptionNameOut}\",\n" .
" .val = ${strOptionFlag} PARSE_RESET_FLAG | ${strOptionVal},\n" .
" },\n";
}
2017-11-28 21:44:05 -05:00
}
}
}
# The option list needs to be terminated or getopt_long will just keep on reading
$strBuildSource .=
" // Terminate option list\n" .
" {\n" .
" .name = NULL\n" .
" }\n" .
"};\n";
$rhBuild->{&BLD_FILE}{&BLDLCL_FILE_DEFINE}{&BLD_DATA}{&BLDLCL_DATA_OPTION_GETOPT}{&BLD_SOURCE} = $strBuildSource;
2017-11-28 21:44:05 -05:00
# Build option resolve order list. This allows the option validation in C to take place in a single pass.
#
# Always process the stanza option first since confusing error message are produced if it is missing.
#-------------------------------------------------------------------------------------------------------------------------------
my @stryResolveOrder = (buildConfigOptionEnum(CFGOPT_STANZA));
my $rhResolved = {&CFGOPT_STANZA => true};
my $bAllResolved;
do
{
# Assume that we will finish on this loop
$bAllResolved = true;
# Loop through all options
foreach my $strOption (sort(keys(%{$rhConfigDefine})))
{
my $bSkip = false;
# Check the default depend
my $strOptionDepend =
ref($rhConfigDefine->{$strOption}{&CFGDEF_DEPEND}) eq 'HASH' ?
$rhConfigDefine->{$strOption}{&CFGDEF_DEPEND}{&CFGDEF_DEPEND_OPTION} :
$rhConfigDefine->{$strOption}{&CFGDEF_DEPEND};
if (defined($strOptionDepend) && !$rhResolved->{$strOptionDepend})
{
# &log(WARN, "$strOptionDepend is not resolved");
$bSkip = true;
}
# Check the command depends
foreach my $strCommand (sort(keys(%{$rhConfigDefine->{$strOption}{&CFGDEF_COMMAND}})))
{
my $strOptionDepend =
ref($rhConfigDefine->{$strOption}{&CFGDEF_COMMAND}{$strCommand}{&CFGDEF_DEPEND}) eq 'HASH' ?
$rhConfigDefine->{$strOption}{&CFGDEF_COMMAND}{$strCommand}{&CFGDEF_DEPEND}{&CFGDEF_DEPEND_OPTION} :
$rhConfigDefine->{$strOption}{&CFGDEF_COMMAND}{$strCommand}{&CFGDEF_DEPEND};
if (defined($strOptionDepend) && !$rhResolved->{$strOptionDepend})
{
$bSkip = true;
}
}
# If dependency was not found try again on the next loop
if ($bSkip)
{
$bAllResolved = false;
}
# Else add option to resolve order list
elsif (!$rhResolved->{$strOption})
{
Prepare configuration module for multi-repository support. Refactor the code to allow a dynamic number of indexes for indexed options, e.g. pg-path. Our reliance on getopt_long() still limits the number of indexes we can have per group, but once this limitation is removed the rest of the code should be happy with dynamic numbers of indexes (with a reasonable maximum). Add an option to set a default in each group. This was previously handled by the host-id option but now there is a specific option for each group, pg and repo. These remain internal until they can be fully tested with multi-repo support. They are fully tested for internal usage. Remove the ConfigDefineOption enum and use the ConfigOption enum instead. They are now equal since the indexed options (e.g. cfgOptRepoHost2) have been removed from ConfigOption. Remove the config/config test module and add required tests to the config/parse test module. Parsing is now the only way to load a config so this removes some redundancy. Split new internal config structures and functions into a new header file, config.intern.h. More functions will need to be moved over from config.h but that will need to be done in a future commit to reduce churn. Add repoIdx to repoIsLocal() and storageRepo*(). Multi-repository support requires that repo locality and storage be accessible by index. This allows, for example, multiple repos to be iterated in a loop. This could be done in a separate commit but doesn't seem worth it since the code is related. Remove the type parameter from storageRepoGet(). This parameter existed solely to provide coverage for the case where the storage type was invalid. A better pattern is to check that the type is S3 once all other types have been ruled out.
2020-11-23 15:55:46 -05:00
push(@stryResolveOrder, buildConfigOptionEnum($strOption));
Prepare configuration module for multi-repository support. Refactor the code to allow a dynamic number of indexes for indexed options, e.g. pg-path. Our reliance on getopt_long() still limits the number of indexes we can have per group, but once this limitation is removed the rest of the code should be happy with dynamic numbers of indexes (with a reasonable maximum). Add an option to set a default in each group. This was previously handled by the host-id option but now there is a specific option for each group, pg and repo. These remain internal until they can be fully tested with multi-repo support. They are fully tested for internal usage. Remove the ConfigDefineOption enum and use the ConfigOption enum instead. They are now equal since the indexed options (e.g. cfgOptRepoHost2) have been removed from ConfigOption. Remove the config/config test module and add required tests to the config/parse test module. Parsing is now the only way to load a config so this removes some redundancy. Split new internal config structures and functions into a new header file, config.intern.h. More functions will need to be moved over from config.h but that will need to be done in a future commit to reduce churn. Add repoIdx to repoIsLocal() and storageRepo*(). Multi-repository support requires that repo locality and storage be accessible by index. This allows, for example, multiple repos to be iterated in a loop. This could be done in a separate commit but doesn't seem worth it since the code is related. Remove the type parameter from storageRepoGet(). This parameter existed solely to provide coverage for the case where the storage type was invalid. A better pattern is to check that the type is S3 once all other types have been ruled out.
2020-11-23 15:55:46 -05:00
$rhResolved->{$strOption} = true;
}
}
}
while (!$bAllResolved);
$rhBuild->{&BLD_FILE}{&BLDLCL_FILE_DEFINE}{&BLD_DATA}{&BLDLCL_DATA_OPTION_RESOLVE}{&BLD_SOURCE} =
"static const ConfigOption optionResolveOrder[] =\n" .
"{\n" .
" " . join(",\n ", @stryResolveOrder) . ",\n" .
"};\n";
2017-11-28 21:44:05 -05:00
return $rhBuild;
}
push @EXPORT, qw(buildConfigParse);
1;