1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00

Improvements to documentation engine:

* Documentation can now be built with reusable blocks to reduce duplication.
* Added ability to pass options to containers within the documentation.
* Add proper tag to slightly emphasize proper nouns.
This commit is contained in:
David Steele 2017-02-10 10:22:05 -05:00
parent aab763d558
commit 498f52da09
7 changed files with 172 additions and 17 deletions

View File

@ -518,13 +518,75 @@ sub nodeRemove
if (!$bRemove)
{
confess &log(ERROR, "child was not found in node");
confess &log(ERROR, "child was not found in node, could not be removed");
}
# Return from function and log return values if any
return logDebugReturn($strOperation);
}
####################################################################################################################################
# nodeReplace
#
# Replace a child node with one or more child nodes.
####################################################################################################################################
sub nodeReplace
{
my $self = shift;
# Assign function parameters, defaults, and log debug info
my
(
$strOperation,
$oChildRemove,
$oyChildReplace,
) =
logDebugParam
(
__PACKAGE__ . '->nodeReplace', \@_,
{name => 'oChildRemove', trace => true},
{name => 'oChildReplace', trace => true},
);
my $bReplace = false;
my $iReplaceIdx = undef;
my $iReplaceTotal = undef;
my $oDoc = $self->{oDoc};
# Error if there are no children
if (!defined($$oDoc{children}))
{
confess &log(ERROR, "node has no children");
}
for (my $iIndex = 0; $iIndex < @{$$oDoc{children}}; $iIndex++)
{
if ($$oDoc{children}[$iIndex] == $oChildRemove->{oDoc})
{
splice(@{$$oDoc{children}}, $iIndex, 1);
splice(@{$$oDoc{children}}, $iIndex, 0, @{$oyChildReplace});
$iReplaceIdx = $iIndex;
$iReplaceTotal = scalar(@{$oyChildReplace});
$bReplace = true;
last;
}
}
if (!$bReplace)
{
confess &log(ERROR, "child was not found in node, could not be replaced");
}
# Return from function and log return values if any
return logDebugReturn
(
$strOperation,
{name => 'iReplaceIdx', value => $iReplaceIdx, trace => true},
{name => 'iReplaceTotal', value => $iReplaceTotal, trace => true},
);
}
####################################################################################################################################
# nameGet
####################################################################################################################################

View File

@ -558,7 +558,9 @@ sub backrestConfig
# Save the ini file
iniSave($strLocalFile, $self->{config}{$strHostName}{$$hCacheKey{file}}, true);
$oHost->copyTo($strLocalFile, $$hCacheKey{file}, $oConfig->paramGet('owner', false, 'postgres:postgres'), '640');
$oHost->copyTo(
$strLocalFile, $$hCacheKey{file},
$self->{oManifest}->variableReplace($oConfig->paramGet('owner', false, 'postgres:postgres')), '640');
# Remove the log-console-stderr option before pushing into the cache
# ??? This is not very pretty and should be replaced with a general way to hide config options
@ -764,6 +766,11 @@ sub hostKey
image => $self->{oManifest}->variableReplace($oHost->paramGet('image')),
};
if (defined($oHost->paramGet('option', false)))
{
$$hCacheKey{option} = $self->{oManifest}->variableReplace($oHost->paramGet('option'));
}
if (defined($oHost->paramGet('os', false)))
{
$$hCacheKey{os} = $self->{oManifest}->variableReplace($oHost->paramGet('os'));
@ -958,7 +965,7 @@ sub sectionChildProcess
my $oHost = new pgBackRestTest::Common::HostTest(
$$hCacheKey{name}, "doc-$$hCacheKey{name}", $$hCacheKey{image}, $$hCacheKey{user}, $$hCacheKey{os},
defined($$hCacheKey{mount}) ? [$$hCacheKey{mount}] : undef);
defined($$hCacheKey{mount}) ? [$$hCacheKey{mount}] : undef, $$hCacheKey{option});
$self->{host}{$$hCacheKey{name}} = $oHost;
$self->{oManifest}->variableSet("host-$$hCacheKey{name}-ip", $oHost->{strIP}, true);

View File

@ -9,6 +9,8 @@ use Carp qw(confess);
use Exporter qw(import);
our @EXPORT = qw();
use JSON::PP;
use Storable qw(dclone);
use pgBackRest::Common::Log;
use pgBackRest::Common::String;
@ -48,6 +50,7 @@ my $oRenderTag =
# 'code-block' => ['```', '```'],
# 'exe' => [undef, ''],
'backrest' => [undef, ''],
'proper' => ['', ''],
'postgres' => ['PostgreSQL', '']
},
@ -73,6 +76,7 @@ my $oRenderTag =
'code-block' => ['', ''],
'exe' => [undef, ''],
'backrest' => [undef, ''],
'proper' => ['', ''],
'postgres' => ['PostgreSQL', '']
},
@ -103,6 +107,7 @@ my $oRenderTag =
# 'code-block' => ['', ''],
# 'exe' => [undef, ''],
'backrest' => [undef, ''],
'proper' => ['\textnormal{\texttt{', '}}'],
'postgres' => ['PostgreSQL', '']
},
@ -130,6 +135,7 @@ my $oRenderTag =
'exe' => [undef, ''],
'setting' => ['<span class="br-setting">', '</span>'], # ??? This will need to be fixed
'backrest' => [undef, ''],
'proper' => ['<span class="host">', '</span>'],
'postgres' => ['<span class="postgres">PostgreSQL</span>', '']
}
};
@ -160,6 +166,9 @@ sub new
{name => 'strRenderOutKey', required => false}
);
# Create JSON object
$self->{oJSON} = JSON::PP->new()->allow_nonref();
# Initialize project tags
$$oRenderTag{markdown}{backrest}[0] = "{[project]}";
$$oRenderTag{markdown}{exe}[0] = "{[project-exe]}";
@ -373,6 +382,56 @@ sub build
$oNode->paramSet('section', $strNewPath);
}
}
# Store block defines
elsif ($strName eq 'block-define')
{
my $strBlockId = $oNode->paramGet('id');
if (defined($self->{oyBlockDefine}{$strBlockId}))
{
confess &log(ERROR, "block ${strBlockId} is already defined");
}
$self->{oyBlockDefine}{$strBlockId} = dclone($oNode->{oDoc}{children});
$oParent->nodeRemove($oNode);
# use Data::Dumper; confess "DATA" . Dumper($self->{oyBlockDefine});
# confess "GOT HERE";
}
# Copy blocks
elsif ($strName eq 'block')
{
my $strBlockId = $oNode->paramGet('id');
if (!defined($self->{oyBlockDefine}{$strBlockId}))
{
confess &log(ERROR, "block ${strBlockId} is not defined");
}
my $strNodeJSON = $self->{oJSON}->encode($self->{oyBlockDefine}{$strBlockId});
foreach my $oVariable ($oNode->nodeList('block-variable-replace'))
{
my $strVariableKey = $oVariable->paramGet('key');
my $strVariableReplace = $oVariable->valueGet();
$strNodeJSON =~ s/\{\[$strVariableKey\]\}/$strVariableReplace/g;
}
my ($iReplaceIdx, $iReplaceTotal) = $oParent->nodeReplace($oNode, $self->{oJSON}->decode($strNodeJSON));
# Build any new children that were added
my $iChildIdx = 0;
foreach my $oChild ($oParent->nodeList(undef, false))
{
if ($iChildIdx >= $iReplaceIdx && $iChildIdx < ($iReplaceIdx + $iReplaceTotal))
{
$self->build($oChild, $oParent, $strPath, $strPathPrefix);
}
$iChildIdx++;
}
}
# Iterate all text nodes
if (defined($oNode->textGet(false)))

View File

@ -426,7 +426,7 @@ li.list-unordered
/*******************************************************************************
Keywords
*******************************************************************************/
.backrest, .cmd, .postgres, .host
.backrest, .cmd, .postgres, .host, .proper
{
font-weight: 500;
}

View File

@ -1,5 +1,5 @@
<!ELEMENT doc ((description, intro, contributor-list, release-list)|(config, operation)|
(description?, variable-list?, cleanup?, section+))>
(description?, variable-list?, block-define*, cleanup?, section+))>
<!ATTLIST doc title CDATA #REQUIRED>
<!ATTLIST doc subtitle CDATA "">
<!ATTLIST doc toc CDATA "y">
@ -113,14 +113,24 @@
<!ELEMENT section (title?,
((p|list|table|host-add|execute-list|backrest-config|postgres-config|cmd-description|
option-description|code-block)+|
((p|list)*, section+)|(p|list)*))>
option-description|code-block|block|section)+))>
<!ATTLIST section id CDATA #REQUIRED>
<!ATTLIST section keyword CDATA "">
<!ATTLIST section depend CDATA "">
<!ATTLIST section source CDATA "">
<!ELEMENT title (#PCDATA|quote|b|i|bi|ul|ol|id|code|host|file|path|cmd|setting|exe|backrest|postgres|br-option|br-setting|
pg-option|pg-setting|link|user)*>
pg-option|pg-setting|link|user|proper)*>
<!ELEMENT block-define (
((p|list|table|host-add|execute-list|backrest-config|postgres-config|cmd-description|
option-description|code-block|block)+|
((p|list)*, section+)|(p|list)*))>
<!ATTLIST block-define id CDATA #REQUIRED>
<!ELEMENT block (block-variable-replace+)>
<!ATTLIST block id CDATA #REQUIRED>
<!ELEMENT block-variable-replace (#PCDATA)>
<!ATTLIST block-variable-replace key CDATA #REQUIRED>
<!ELEMENT default (#PCDATA)>
<!ELEMENT allow (#PCDATA)>
@ -175,6 +185,7 @@
<!ATTLIST host-add name CDATA #REQUIRED>
<!ATTLIST host-add user CDATA #REQUIRED>
<!ATTLIST host-add image CDATA #REQUIRED>
<!ATTLIST host-add option CDATA "">
<!ATTLIST host-add os CDATA "">
<!ATTLIST host-add mount CDATA "">
@ -184,32 +195,32 @@
<!ELEMENT table-header (table-column+)>
<!ATTLIST table-header width CDATA "">
<!ELEMENT table-column (#PCDATA|quote|b|i|id|code|host|file|path|cmd|setting|exe|backrest|postgres|br-option|
br-setting|pg-option|pg-setting|link|user)*>
br-setting|pg-option|pg-setting|link|user|proper)*>
<!ATTLIST table-column align CDATA "">
<!ATTLIST table-column fill CDATA "">
<!ELEMENT table-data (table-row+)>
<!ELEMENT table-row (table-cell+)>
<!ELEMENT table-cell (#PCDATA|quote|b|i|ul|ol|id|code|code-block|host|file|path|cmd|setting|exe|backrest|postgres|br-option|
br-setting|pg-option|pg-setting|link|user)*>
br-setting|pg-option|pg-setting|link|user|proper)*>
<!-- Formatted elements -->
<!ELEMENT summary (#PCDATA|quote|b|i|ul|ol|id|code|code-block|host|file|path|cmd|setting|exe|backrest|postgres|br-option|
br-setting|pg-option|pg-setting|link|user)*>
br-setting|pg-option|pg-setting|link|user|proper)*>
<!ELEMENT p (#PCDATA|quote|b|i|id|code|code-block|host|file|path|cmd|setting|exe|backrest|postgres|br-option|br-setting|
pg-option|pg-setting|link|user)*>
pg-option|pg-setting|link|user|proper)*>
<!ATTLIST p keyword CDATA "">
<!ELEMENT text (#PCDATA|quote|b|i|ul|ol|id|code|code-block|host|file|path|cmd|setting|exe|backrest|postgres|br-option|
br-setting|pg-option|pg-setting|link|user)*>
br-setting|pg-option|pg-setting|link|user|proper)*>
<!ELEMENT i (#PCDATA)>
<!ELEMENT b (#PCDATA)>
<!ELEMENT ul (li+)>
<!ELEMENT ol (li+)>
<!ELEMENT li (#PCDATA|quote|b|i|ul|ol|id|code|code-block|host|file|path|cmd|setting|exe|backrest|postgres|br-option|
br-setting|pg-option|pg-setting|link|user)*>
br-setting|pg-option|pg-setting|link|user|proper)*>
<!ELEMENT list (list-item+)>
<!ELEMENT list-item (#PCDATA|quote|b|i|ul|ol|id|code|code-block|host|file|path|cmd|setting|exe|backrest|postgres|br-option|
br-setting|pg-option|pg-setting|link|user)*>
br-setting|pg-option|pg-setting|link|user|proper)*>
<!ELEMENT id (#PCDATA)>
<!ELEMENT code (#PCDATA)>
<!ELEMENT code-block (#PCDATA|exe)*>
@ -221,6 +232,7 @@
<!ELEMENT cmd (#PCDATA)>
<!ELEMENT user (#PCDATA)>
<!ELEMENT quote (#PCDATA)>
<!ELEMENT proper (#PCDATA)>
<!ELEMENT setting (#PCDATA)>
<!ELEMENT br-option (#PCDATA)>
<!ELEMENT br-setting (#PCDATA)>

View File

@ -158,6 +158,18 @@
<p>Updated async archiving documentation to more accurately describe how the new method works and how it differs from the old method.</p>
</release-item>
<release-item>
<p>Documentation can now be built with reusable blocks to reduce duplication.</p>
</release-item>
<release-item>
<p>Added ability to pass options to containers within the documentation.</p>
</release-item>
<release-item>
<p>Add <code>proper</code> tag to slightly emphasize proper nouns.</p>
</release-item>
</release-feature-list>
</release-doc-list>
</release>

View File

@ -38,7 +38,8 @@ sub new
$self->{strImage},
$self->{strUser},
$self->{strOS},
$self->{stryMount}
$self->{stryMount},
$self->{strOption},
) =
logDebugParam
(
@ -48,12 +49,14 @@ sub new
{name => 'strImage', trace => true},
{name => 'strUser', trace => true},
{name => 'strOS', trace => true},
{name => 'stryMount', required => false, trace => true}
{name => 'stryMount', required => false, trace => true},
{name => 'strOption', required => false, trace => true},
);
executeTest("docker rm -f $self->{strContainer}", {bSuppressError => true});
executeTest("docker run -itd -h $self->{strName} --name=$self->{strContainer}" .
(defined($self->{strOption}) ? ' ' . $self->{strOption} : '') .
(defined($self->{stryMount}) ? ' -v ' . join(' -v ', @{$self->{stryMount}}) : '') .
" $self->{strImage}");