Private/Get-HDTStepPartitionItem.ps1
|
function Get-HDTStepPartitionItem { <# .SYNOPSIS Where each row of a step's partition table starts and ends. .DESCRIPTION THE LOCATOR THE THREE EDITING COMMANDS SHARE. Add, Remove and Move all have to answer the same question first - which lines does the partition called 'Windows' own - and answering it three times is answering it differently twice. AN ITEM OWNS EVERY LINE UNTIL THE NEXT DASH AT ITS OWN COLUMN, which is what makes a multi-line row work: partition: - name: Windows <- Index type: Primary size: 60% <- End COMMENTS ABOVE A ROW BELONG TO IT. An administrator writing "# the volume the OS lands on" above a partition means it about that partition, and a move that left the comment behind would attach it to whatever slid into its place. IT FINDS NOTHING WHEN THE STEP NAMES A LAYOUT INSTEAD, and that is an ordinary answer rather than an error - the caller says what to do about it, because Add and Remove have different things to say. .PARAMETER Line The sequence document's lines. .PARAMETER Block The step, from Resolve-HDTStepBlock. .INPUTS None. This command does not accept pipeline input. .OUTPUTS System.Management.Automation.PSCustomObject[] in document order: Name the partition's name Index the line its dash sits on Start Index, or the first comment line above it End the last line it owns Indent the column the dash sits at, which an insert must match .EXAMPLE Get-HDTStepPartitionItem -Line $line -Block (Resolve-HDTStepBlock -Line $line -Name 'Format and Partition') #> [CmdletBinding()] [OutputType([pscustomobject[]])] param( [Parameter(Mandatory = $true, Position = 0)] [AllowEmptyCollection()] [AllowEmptyString()] [string[]] $Line, [Parameter(Mandatory = $true, Position = 1)] [ValidateNotNull()] [object] $Block ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $key = Get-HDTStepKey -Line $Line -Block $Block -Key 'partition' if ([int] $key.Index -lt 0) { return [pscustomobject[]] @() } $item = New-Object -TypeName System.Collections.ArrayList $current = $null $itemIndent = -1 for ($index = [int] $key.Index + 1; $index -le [int] $Block.End; $index++) { $text = [string] $Line[$index] if ([string]::IsNullOrWhiteSpace($text)) { continue } $indent = $text.Length - $text.TrimStart(' ').Length $trimmed = $text.TrimStart(' ') # BACK OUT TO THE KEY'S OWN COLUMN AND THE LIST IS OVER - the next key # of the step has started. if ($indent -le [int] $key.Indent -and -not $trimmed.StartsWith('- ')) { break } if ($trimmed.StartsWith('- ')) { if ($itemIndent -lt 0) { $itemIndent = $indent } if ($indent -ne $itemIndent) { continue } $name = '' if ($trimmed -match '^-\s+name:\s*(.+?)\s*$') { $name = [string] $Matches[1].Trim('"', "'") } $current = [pscustomobject] @{ Name = $name Index = $index Start = $index End = $index Indent = $indent } # THE COMMENTS ABOVE IT ARE PART OF IT. Walk back over any comment # lines written at the item's own column or deeper. $above = $index - 1 while ($above -gt [int] $key.Index) { $previous = [string] $Line[$above] if (-not $previous.TrimStart(' ').StartsWith('#')) { break } $current.Start = $above $above-- } [void] $item.Add($current) continue } if ($null -ne $current) { $current.End = $index } } return [pscustomobject[]] @($item) } |