refactor:

This commit is contained in:
Rodweil, Theodor 2023-08-13 22:11:57 +02:00
parent 0d4751ff68
commit 88aae9e3a6
No known key found for this signature in database
GPG key ID: F8BC1B0EB1F9CCF5
5 changed files with 578 additions and 328 deletions

View file

@ -92,6 +92,22 @@ to exist.
Publish-Page
```
## Compatibility
This program is compatible with the following Microsoft PowerShell runtimes:
- Microsoft PowerShell Desktop >=5
- Microsoft PowerShell Core >=7
## Runtime Dependencies
This program has no runtime dependencies.
On PowerShell Desktop, however, it is necessary to obtain the
`Microsoft.PowerShell.Utility` module for JSON schema verification of the
manifest. Whether that's possible for PowerShell Desktop; We do not know.
Should the aforementioned module not be present, JSON validation is skipped.
## Debugging
To display debug messages, set
@ -108,7 +124,13 @@ Execute `pwsh scripts/analyze.ps1` to do a static code analysis.
## Testing
This program requires [Pester v5](https://pester.dev/) to execute it's test suite.
This program requires [Pester](https://pester.dev/) to execute it's test suite.
The test suite aims to be executable under most circumstances. We've been
dropping usage of Pester v5 functionalities so that it works with Pester down
to version 3, since Pester v3 is available in PowerShell (5) Desktop by default.
Due to the security mechanisms implemented in PowerShell Desktop, installing the
Pester v5 module may not be feasible for some.
Execute `pwsh scripts/test.ps1` to run the entire test suite.
@ -116,9 +138,13 @@ Execute `pwsh scripts/test.ps1` to run the entire test suite.
This program does not adhere to Microsoft's Best-Practices of publishing
PowerShell modules, in the sense of that it does not use the *PowerShellGet*
module to do so and uses plain `nuget` CLI instead.
module to do so and uses the plain `nuget` CLI instead.
Execute `pwsh scripts/pack.ps1` to create a nuget package.
This program requires [nuget
CLI](https://learn.microsoft.com/en-us/nuget/install-nuget-client-tools). Be
aware that the `dotnet nuget` CLI may not be sufficient on some platforms.
Execute `pwsh scripts/publish` to publish the nuget package to
Execute `pwsh scripts/pack.ps1` to create the nuget package.
Execute `pwsh scripts/publish.ps1` to publish the nuget package to
[PowerShellGallery](https://www.powershellgallery.com).

View file

@ -2,9 +2,8 @@
$ErrorActionPreference = "Stop"
$script:schema = Get-Content (
Join-Path -Path $PSScriptRoot 'schemas' 'manifest.schema.json'
) | Out-String
$script:schema = Get-Content `
"$PSScriptRoot/schemas/manifest.schema.json" | Out-String
function Get-Manifest
@ -21,6 +20,11 @@ function Get-Manifest
[Parameter(Mandatory)] [string] $File
)
Begin
{
$basePath = Split-Path $File
}
Process
{
try
@ -35,9 +39,59 @@ function Get-Manifest
$raw = '{"Pages":[], "attachments": []}'
}
$raw | Test-JSON -Schema $script:schema | Out-Null
If ($PSVersionTable.PSEdition -eq 'Core')
{
$raw | Test-JSON -Schema $script:schema | Out-Null
}
$raw | ConvertFrom-JSON
$manifest = $raw | ConvertFrom-JSON
ForEach($pageMeta in $manifest.Pages)
{
# patching to be an absolute path, the inverse function
# (Set-Manifest) must check, whether _Ref is set and substitute for
# Ref before writing to filesystem
If ($pageMeta.Ref)
{
$pageMeta | Add-Member `
-NotePropertyName '_Ref' `
-NotePropertyValue $pageMeta.Ref `
-Force
$pageMeta | Add-Member `
-NotePropertyName 'Ref' `
-NotePropertyValue (
Join-Path $basePath $pageMeta.Ref | Resolve-Path
) `
-Force
}
}
ForEach($attachmentMeta in $manifest.Attachments)
{
# patching to be an absolute path, the inverse function
# (Set-Manifest) must check, whether _Ref is set and substitute for
# Ref before writing to filesystem
If ($attachmentMeta.Ref)
{
$attachmentMeta | Add-Member `
-NotePropertyName '_Ref' `
-NotePropertyValue $attachmentMeta.Ref `
-Force
$attachmentMeta | Add-Member `
-NotePropertyName 'Ref' `
-NotePropertyValue (
Join-Path $basePath $attachmentMeta.Ref | Resolve-Path
) `
-Force
}
}
}
End
{
$manifest
}
}
@ -62,9 +116,38 @@ function Set-Manifest
Process
{
ForEach($pageMeta in $Manifest.Pages)
{
# patching to be an absolute path, the inverse function
# (Set-Manifest) must check, whether _Ref is set and substitute for
# Ref before writing to filesystem
If ($pageMeta._Ref)
{
$pageMeta.Ref = $pageMeta._Ref
$Manifest.Pages.PSObject.Properties.Remove('_Ref')
}
}
ForEach($attachmentMeta in $Manifest.Attachments)
{
# patching to be an absolute path, the inverse function
# (Set-Manifest) must check, whether _Ref is set and substitute for
# Ref before writing to filesystem
If ($attachmentMeta._Ref)
{
$attachmentMeta.Ref = $attachmentMeta._Ref
$Manifest.Attachments.PSObject.Properties.Remove('_Ref')
}
}
$raw = $Manifest | ConvertTo-JSON
$raw | Test-JSON -Schema $script:schema
If ($PSVersionTable.PSEdition -eq 'Core')
{
$raw | Test-JSON -Schema $script:schema
}
if ($Backup)
{
@ -136,7 +219,7 @@ function New-AncestralPageGenerationCache {
{
$generation = 0
$pageMeta = $Title ? $Manifest[$Index.$Title] : $pageMeta
$pageMeta = If ($Title) {$Manifest[$Index.$Title]} Else {$pageMeta}
$ancestor = $pageMeta.AncestorTitle

View file

@ -33,3 +33,112 @@
$ErrorActionPreference = "Stop"
function Initialize-Manifest
{
<#
#>
Param(
# path of manifest to load
[Parameter(Mandatory)] [String] $Path
)
Begin
{
$literalPath = Resolve-Path -Path $Path
}
Process
{
Write-Debug 'loading manifest...'
$manifest = Get-Manifest $literalPath
Write-Debug 'creating pages manifest index...'
$pagesManifestIndex = New-PagesManifestIndex -Manifest $manifest.Pages
Write-Debug 'creating ancestral page generation cache...'
$ancestralGenerationCache = New-AncestralPageGenerationCache `
-Manifest $manifest.Pages `
-Index $pagesManifestIndex
Write-Debug 'sorting pages manifest...'
Optimize-PagesManifest `
-Manifest $manifest.Pages `
-Lo 0 `
-Hi ($manifest.Pages.Count - 1) `
-GenerationCache $ancestralGenerationCache | Out-Null
}
End
{
@{
'Path' = $literalPath
'Manifest' = $manifest
'Index' = @{
'Pages' = New-PagesManifestIndex `
-Manifest $manifest.Pages
'Attachments' = New-AttachmentsManifestIndex `
-Manifest $manifest.Attachments
}
}
}
}
function Initialize-Connection
{
Param(
[Parameter(Mandatory)] [String]$Host,
[Parameter(Mandatory)] [String]$Space,
[Parameter(Mandatory)] [String]$PersonalAccessToken
)
Process
{
Register-PersonalAccessToken `
-Host $Host `
-Token $PersonalAccessToken | Out-Null
Test-Connection -Host $Host | Out-Null
}
End
{
@{
'Host' = $Host
'Space' = $Space
}
}
}
function Publish-Pages
{
Param(
# connection object created through Initialize-Connection
[Parameter(Mandatory)] [Collections.Hashtable]$Connection,
# manifest object created through Initialize-Manifest
[Parameter(Mandatory)] [PSCustomObject]$Manifest,
#
[Parameter()] [Switch]$Strict,
#
[Parameter()] [Switch]$Force,
# title of page to be published
[Parameter()] [String]$Title
)
Process
{
$Manifest.Manifest.Pages | Publish-Page `
-Host $Connection.Host `
-Space $Connection.Space `
-Title $Title `
-Index $Manifest.Index.Pages `
-Strict:$Strict `
-Force:$Force | Out-Null
}
}

View file

@ -38,8 +38,8 @@ function New-Page
# title of page to be published
[Parameter()] [string]$Title,
# pages manifest
[Parameter(Mandatory, ValueFromPipeline)]
[Collections.Hashtable[]]$Manifest,
[Parameter(Mandatory)]
[PSCustomObject[]]$Manifest,
# pages manifest index, mandatory for ancestor lookup
[Parameter(Mandatory)] [Collections.Hashtable]$Index,
# flag on whether to fail hard, or just continue
@ -66,7 +66,8 @@ function New-Page
ElseIf (-Not $pageMeta.Ref)
{
$errMsg = "no reference to local content for page ``$Title``."
$errMsg = ("``$($pageMeta.Title)``: no reference to local " +
'content for page .')
If ($Strict) {throw $errMsg}
@ -78,7 +79,10 @@ function New-Page
ElseIf ($pageMeta.Id)
{
Write-Debug "skipping, page already published: $($pageMeta.Id)"
Write-Debug (
"New-Page: ``$($pageMeta.Title)``: skipping, already " +
"published ($($pageMeta.Id))"
)
$pageMeta
@ -87,13 +91,29 @@ function New-Page
Else
{
$content = Get-Content -Path $pageMeta.Ref
Write-Host "New-Page: ``$($pageMeta.Title)``: creating"
Try
{
$content = Get-Content -Path $pageMeta.Ref | Out-String
}
Catch
{
$errMsg = "``New-Page: $($PageMeta.Title)``: $_"
If ($Strict) {throw $errMsg}
Write-Host $errMsg
continue
}
$contentHash = (Get-StringHash $content).Hash
$transportBody = @{
'type' = 'page'
'title' = $Title
'title' = $pageMeta.Title
'space' = @{
'key' = $Space
}
@ -103,7 +123,7 @@ function New-Page
'representation' = 'storage'
}
}
} | ConvertTo-JSON
} | ConvertTo-JSON -Depth 5
Try
{
@ -120,10 +140,12 @@ function New-Page
Catch
{
$errMsg = "skipping ``$pageMeta.Title``: $_"
$errMsg = "skipping ``$($pageMeta.Title)``: $($_)"
If ($Strict)
{
$_
throw $errMsg
}
@ -141,7 +163,7 @@ function New-Page
$pageMeta | Add-Member `
-NotePropertyName 'Version' `
-NotePropertyValue $response.version.number `
-NotePropertyValue "1" `
-Force
$pageMeta | Add-Member `
@ -176,107 +198,224 @@ function Update-Page
{
<#
.SYNOPSIS
Add a confluence page
Update an existing Confluence page
.DESCRIPTION
This function is unaware of the publishing status of ancestors and
assumes that ancestral hierarchy is maintained through the
manifest's item order, therefore an index must be supplied.
If a page's metadata does not include a reference, it will be
treated as a publishing failure and therefore not output the
original metadata.
.OUTPUTS
When no $Title is provided and the $Manifest array only contains 1
page metadata, the ``Count`` attribute is faulty. Why? Don't know.
.EXAMPLE
Update-ConfluencePage
Add-ConfluencePage `
-Host 'confluence.contoso.com' `
-Space 'TIARA' `
-Title 'Testitest' `
-Manifest @{}
-Content @{}
#>
Param(
[Parameter(Mandatory)] [string] $Host,
# The name of the Confluence space to publish to
[Parameter(Mandatory)] [string] $Space,
# confluence instance hostname
[Parameter(Mandatory)] [string]$Host,
# name of the Confluence space to publish to
[Parameter(Mandatory)] [string]$Space,
# title of page to be published
[Parameter(Mandatory)] [string] $Title,
[Parameter()] [string]$Title,
# pages manifest
[Parameter(Mandatory)] [Array] $Manifest,
# pages manifest index
[Parameter()] [Collections.Hashtable] $Index
[Parameter(Mandatory, ValueFromPipeline)]
[PSCustomObject[]]$Manifest,
# pages manifest index, mandatory for ancestor lookup
[Parameter(Mandatory)] [Collections.Hashtable]$Index,
# flag on whether to fail hard, or just continue
[Parameter()] [Switch]$Strict,
# flag on whether to force update of page, regardless of content
[Parameter()] [Switch]$Force
)
Begin
{
$pat = Get-PersonalAccessToken $Host
}
Process
{
$pageMeta = Get-PageMeta `
-Host $Host `
-Space $Space `
-Title $Title `
-Manifest $Manifest `
-Index $Index
if (-Not $pageMeta.Ref)
If ($Title -And $Manifest[$Index.$Title])
{
throw "no reference to local content for page '$Title'."
$Manifest = @(
$Manifest[$Index.$Title]
)
}
if (-Not $pageMeta.Id)
ForEach($pageMeta in $Manifest)
{
throw "no id for page '$Title'."
}
If ($Title -And $pageMeta.Title -ne $Title) {continue}
$content = Get-Content -Path $pageMeta.Ref
ElseIf (-Not $pageMeta.Ref)
{
$errMsg = "no reference to local content for page ``$Title``."
$hash = (Get-StringHash $content).Hash
If ($Strict) {throw $errMsg}
if ($hash -eq $pageMeta.Hash)
{
Write-Host "content unchanged, skipping: '$Title'"
Write-Host $errMsg
# yep, this is funny... This behaves like a return statement, because
# a cmdlet, treats the input as an array of inputs. We keep it that
# way so that all functions can properly act upon pipes. See
# additional information on 'Process' blocks.
continue
}
# we're not updating this in place, so that we don't have to reset the
# value opon failure
$version = $pageMeta.Version + 1
$transportBody = @{
'id' = $PageMeta.Id
'type' = 'page'
'title' = $Title
'space' = @{
'key' = $Space
continue
}
'body' = @{
'storage' = @{
'value' = $content
'representation' = 'storage'
ElseIf (-Not $pageMeta.Id)
{
$errMsg = "``$($pageMeta.Title)``: unknown page id"
If ($Strict) {throw $errMsg}
Write-Host $errMsg
continue
}
ElseIf (-Not $pageMeta.Version)
{
Write-Host "``$($pageMeta.Title)``: unknown (current) version"
$pageMeta
continue
}
Else
{
Try
{
$content = Get-Content -Path $pageMeta.Ref | Out-String
}
Catch
{
$errMsg = "``$Title``: $_"
If ($Strict) {throw $errMsg}
Write-Host $errMsg
continue
}
$version = [Int]($pageMeta.Version) + 1
$contentHash = (Get-StringHash $content).Hash
If (
$pageMeta.Hash -And
$pageMeta.Hash -eq $contentHash -And
-Not $Force
)
{
Write-Debug (
"Update-Page: ``$($pageMeta.Title)``: skipping, no " +
"content changes"
)
$pageMeta
continue
}
Else
{
Write-Host "``$($pageMeta.Title)``: updating"
}
# status needs to be set as to restore the page, if it is
# trashed
$transportBody = @{
'id' = $PageMeta.Id
'type' = 'page'
'title' = $pageMeta.Title
'space' = @{
'key' = $Space
}
'body' = @{
'storage' = @{
'value' = $content
'representation' = 'storage'
}
}
'status' = 'current'
'version' = @{
'number' = $version
}
} | ConvertTo-JSON -WarningAction 'SilentlyContinue'
Try
{
Invoke-WebRequest `
-Uri ("https://${Host}/rest/api/content/" +
$PageMeta.Id) `
-Method 'Put' `
-Headers @{
'Authorization' = "Bearer $pat"
} `
-ContentType "application/json" `
-Body $transportBody `
-OutVariable rawResponse | Out-Null
}
Catch
{
$errMsg = "skipping ``$($pageMeta.Title)``: $_"
If ($Strict)
{
$_
throw $errMsg
}
Write-Host $errMsg
continue
}
# response isn't needed since no field will be updated by the
# Confluence instance itself
#$response = ($rawResponse.Content | ConvertFrom-JSON)
$pageMeta | Add-Member `
-NotePropertyName 'Version' `
-NotePropertyValue $version `
-Force
$pageMeta | Add-Member `
-NotePropertyName 'Hash' `
-NotePropertyValue $contentHash `
-Force
If (
($Title -And $pageMeta.Title -eq $Title) -Or
$Manifest.Count -eq 1
)
{
# TODO: further research mechanism of expanding single item
# array pipelines. For now we have to apply the unary
# operator, otherwise we get a wrong count on the output
,@($pageMeta)
break
}
Else
{
$pageMeta
}
}
'version' = @{
'number' = $version
}
} | ConvertTo-JSON
Invoke-WebRequest `
-Uri "https://${Host}/rest/api/content/$($PageMeta.Id)" `
-Method 'Put' `
-Headers @{
'Authorization' = "Bearer $(Get-PersonalAccessToken $Host)"
} `
-ContentType "application/json" `
-Body $transportBody `
-OutVariable rawResponse | Out-Null
}
End
{
$response = ($rawResponse.Content | ConvertFrom-JSON)
Update-PageMeta `
-Title $Title `
-Id $pageMeta.Id `
-Version $response.version.number `
-Hash $hash `
-Manifest $Manifest `
-Index $Index
}
}
}
@ -284,82 +423,43 @@ function Update-Page
function Publish-Page
{
Param(
# title of the page (used for manifest lookup)
[Parameter(Mandatory)] [string] $Title,
# hostname of Confluence instance
[Parameter(Mandatory)] [string] $Host,
# name of Confluence space
[Parameter(Mandatory)] [string] $Space,
# manifest object
[Parameter(Mandatory, ValueFromPipeline)] [PSObject] $Meta
# confluence instance hostname
[Parameter(Mandatory)] [string]$Host,
# name of the Confluence space to publish to
[Parameter(Mandatory)] [string]$Space,
# title of page to be published
[Parameter()] [string]$Title,
# pages manifest
[Parameter(Mandatory, ValueFromPipeline)]
[PSCustomObject[]]$Manifest,
# pages manifest index, mandatory for ancestor lookup
[Parameter(Mandatory)] [Collections.Hashtable]$Index,
# flag on whether to fail hard, or just continue
[Parameter()] [Switch]$Strict,
# flag on whether to force update of page, regardless of content
[Parameter()] [Switch]$Force
)
Process
{
ForEach($meta in $Meta)
{
$meta = Get-PageMeta `
-Host $hostname `
-Space $spaceName `
-Title $Title `
-Manifest $Manifest
$result = Update-Page `
-Host $Host `
-Space $Space `
-Manifest $Manifest `
-Index $Index `
-Strict:$Strict `
-Force:$Force
if ($meta.AncestorTitle)
{
$ancestorPageMeta = Get-PageMeta `
-Host $hostname `
-Space $spaceName `
-Title $pageMeta.AncestorTitle `
-Manifest $Manifest
$result = New-Page `
-Host $Host `
-Space $Space `
-Manifest $result `
-Index $Index `
-Strict:$Strict
}
if (-Not ($ancestorPageMeta -Or $ancestorPageMeta.PageId))
{
Write-Host "ancestor, not published, skipping: $Title"
continue
}
}
if (-Not $pageId)
{
Write-Host ("create ${_}: $prettyName")
try {
New-Page `
-Host $hostname `
-Space $spaceName `
-Title $Title `
-Manifest $Manifest
}
catch
{
Write-Host "error for '$Title', skipping: $_"
continue
}
}
else
{
Write-Host ("update ${_} (${pageId}): $prettyName")
try
{
Update-Page `
-Host $hostname `
-Space $Space `
-Title $Title `
-Manifest $Manifest
}
catch
{
Write-Host "error for '$Title', skipping: $_"
continue
}
}
}
End
{
$result
}
}

View file

@ -1,60 +1,7 @@
#!/usr/bin/env pwsh
$ErrorActionPreference = "Stop"
function Get-PageMetaCache
{
<#
.SYNOPSIS
Get a locally indexed/cached Confluence page id
.EXAMPLE
Get-PageMetaCache `
-Title 'Page Title' `
-Manifest @() `
-Index @{}
.NOTES
To test or not to test, that is the question... Since the
`Test-JSON` cmdlet requires serialized JSON, but we are working with
the deserialized Hashtable, it's too computationally intense to
always test the input upon every call. We therefore only make sure,
that correct data is written to the filesystem. For the rest, each
function is responsible for themself (learned that that's a valid
reflexive pronoun today 🤓).
This function is lucky to get this note, because it's at the top 💯.
Of course this applies to every function.
#>
Param(
[Parameter(Mandatory)] [string] $Title,
[Parameter(Mandatory)] [Array] $Manifest,
[Parameter()] [Collections.Hashtable] $Index
)
Process
{
If ($Index -And $Manifest.Count -gt 0 -And $Manifest[$Index.$Title])
{
$Manifest[$Index.$Title]
}
Else
{
For ($i = 0; $i -lt $Manifest.Count; $i += 1)
{
If ($Manifest[$i].Title -eq $Title)
{
$Manifest[$i]
break
}
}
}
}
}
function Get-PageMeta
{
<#
@ -74,127 +21,112 @@ function Get-PageMeta
-CacheIndexFile 'confluence-page-cache.json'
#>
Param(
# Confluence instance hostname
[Parameter(Mandatory)] [string] $Host,
[Parameter(Mandatory)] [string] $Title,
# Page title
[Parameter()] [string] $Title,
# Confluence space id
[Parameter(Mandatory)] [string] $Space,
[Parameter(Mandatory)] [Array] $Manifest,
[Parameter()] [Collections.Hashtable] $Index
# pages manifest
[Parameter(Mandatory, ValueFromPipeline)] [Array] $Manifest,
# page metadata index for faster lookup of single page
[Parameter()] [Collections.Hashtable] $Index,
# force to get metadata from remote
[Parameter()] [Switch] $Force = $false,
# throw an exception on error
[Parameter()] [Switch] $Strict = $true
)
Begin
{
$pageMeta = Get-PageMetaCache `
-Title $Title `
-Manifest $Manifest `
-Index $Index
}
Process
{
If ($pageMeta -And $pageMeta.Id)
If ($Title -And $Index -And $Manifest[$Index.$Title].Id)
{
$pageMeta
$Manifest[$Index.$Title]
return
}
$escapedTitle = [Uri]::EscapeDataString($Title)
#TODO: move this to a separate function
$query = "title=${escapedTitle}&spaceKey=${Space}&expand=history"
Invoke-WebRequest `
-Uri "https://${Host}/rest/api/content?$query" `
-Method 'Get' `
-Headers @{
'Authorization' = "Bearer $(Get-PersonalAccessToken $Host)"
} `
-OutVariable response | Out-Null
$results = ($response.Content | ConvertFrom-JSON).results
if ($results.Count -gt 1)
ForEach ($pageMeta in $Manifest)
{
throw "more than one result for query: $query"
}
If ($Title -And $pageMeta.Title -ne $Title) {continue}
elseif ($results.Count -eq 1)
{
Update-PageMeta `
-Id $results[0].id `
-Version $results[0]._expandable.version `
-Title $Title `
-Manifest $Manifest
If ($pageMeta.Id -And -Not $Force)
{
Write-Debug "local (cache): $($pageMeta.Title) ($($pageMeta.Id))"
$pageMeta
}
Else
{
$escapedTitle = [Uri]::EscapeDataString($pageMeta.Title)
$query = (
"title=${escapedTitle}&spaceKey=${Space}&expand=version"
)
Invoke-WebRequest `
-Uri "https://${Host}/rest/api/content?$query" `
-Method 'Get' `
-Headers @{
'Authorization' = 'Bearer ' +
$(Get-PersonalAccessToken $Host)
} `
-OutVariable response | Out-Null
$results = ($response.Content | ConvertFrom-JSON).results
If ($results.Count -gt 1)
{
$errMsg = "error: more than one result for query: $query"
If ($Strict) {throw $errMsg}
Write-Host $errMsg
$pageMeta
continue
}
ElseIf ($results.Count -eq 1)
{
Write-Debug (
"Get-PageMetadata: ``$($pageMeta.Title)``: " +
"updating metadata through remote ($($results[0].id))"
)
$pageMeta | Add-Member `
-NotePropertyName Id `
-NotePropertyValue $results[0].id `
-Force
$pageMeta | Add-Member `
-NotePropertyName 'Version' `
-NotePropertyValue `
$results[0].version.number `
-Force
}
Else
{
Write-Debug "local: $($pageMeta.Title) (no remote)"
}
If (-Not $pageMeta.Hash)
{
$content = Get-Content $pageMeta.Ref | Out-String
$hash = (Get-StringHash $content).Hash
$pageMeta | Add-Member `
-NotePropertyName 'Hash' `
-NotePropertyValue $hash `
-Force
}
$pageMeta
}
}
}
}
function Update-PageMeta
{
<#
.SYNOPSIS
Register a Confluence page's metadata in the local cache
.DESCRIPTION
Synchronizes the locally cached page metadata (in manifest) with the
data stored by the Confluence instance. Therefore it is required to
supply a page id, since this is the reference linking the locally
cached page to a published instance of a page.
.EXAMPLE
Update-PageMeta `
-Title 'foobar' `
-PageId 'pageId' `
-Version 9001 `
-AncestorTitle 'ancestorTitle' `
-Hash 'hash' `
-Manifest $mockManifest
#>
Param(
[Parameter(Mandatory)] [String] $Title,
# remote Confluence page instance id
[Parameter(Mandatory)] [String] $Id,
[Parameter()] [Int] $Version,
[Parameter()] [String] $AncestorTitle,
[Parameter()] [String] $Hash,
[Parameter(Mandatory)] [Array] $Manifest,
[Parameter()] [Collections.Hashtable] $Index
)
Process
{
$pageMeta = Get-PageMetaCache `
-Title $Title `
-Manifest $Manifest `
-Index $Index
If (-Not $pageMeta)
{
throw "page titled `$Title` not indexed in Manifest."
}
$pageMeta.Id = $Id
If ($Version)
{
$pageMeta.Version = $Version
}
If ($AncestorTitle)
{
$pageMeta.AncestorTitle = $AncestorTitle
}
# if content didn't update, hash stays the same
If ($Hash)
{
$pageMeta.Hash = $Hash
}
Write-Debug "register: $Title -> $PageId"
$pageMeta
}
}