You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +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:
		| @@ -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 | ||||
| #################################################################################################################################### | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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))) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user