private/BuildTree.ps1
|
function BuildTree { param([string]$Dir, [string]$Root, [int]$CurrentDepth) $relPath = if ($Dir -eq $Root) { "" } else { $Dir.Substring($Root.Length).TrimStart([System.IO.Path]::DirectorySeparatorChar).Replace([System.IO.Path]::DirectorySeparatorChar, '/') } $displayName = if ($Dir -eq $Root) { Split-Path $Root -Leaf } else { Split-Path $Dir -Leaf } $stats = ScanDir -Dir $Dir -Root $Root $type = if ($stats.IsRoot) { "Root" } else { "Bucket" } $node = [PSCustomObject]@{ Name = $displayName Type = $type Path = $relPath ObjectCount = $stats.ObjectCount SizeBytes = $stats.SizeBytes Depth = $CurrentDepth Children = [System.Collections.ArrayList]::new() _BucketName = if ($stats.IsBucket -and -not $stats.IsRoot) { $relPath } else { "" } _BucketKey = "" } $node.PSObject.TypeNames.Insert(0, "Buckets.Tree") $di = [System.IO.DirectoryInfo]::new($Dir) $subDirs = @() foreach ($sub in ($di.GetDirectories() | Sort-Object Name)) { if ($sub.Name -eq ".buckets") { continue } $subRelPath = $sub.FullName.Substring($Root.Length).TrimStart([System.IO.Path]::DirectorySeparatorChar).Replace([System.IO.Path]::DirectorySeparatorChar, '/') if (-not [string]::IsNullOrWhiteSpace($script:TreeNameFilter)) { $subRelPathSlash = $subRelPath.TrimEnd('/') + '/' $filterSlash = $script:TreeNameFilter.TrimEnd('/') + '/' $subContainedInFilter = $filterSlash.StartsWith($subRelPathSlash) $filterContainedInSub = $subRelPathSlash.StartsWith($filterSlash) if (-not $subContainedInFilter -and -not $filterContainedInSub) { continue } } $subHasFiles = $sub.Exists -and ($sub.GetFiles("*.dat").Length -gt 0 -or $sub.GetFiles("*.json").Length -gt 0) $subStats = if ($sub.Exists) { ScanDir -Dir $sub.FullName -Root $Root } else { @{ ObjectCount = 0; SizeBytes = 0; BucketCount = 0 } } if ($subHasFiles -or $subStats.BucketCount -gt 0) { $subDirs += $sub } } foreach ($sub in $subDirs) { if ($CurrentDepth -lt $Depth -or $Objects) { $child = BuildTree -Dir $sub.FullName -Root $Root -CurrentDepth ($CurrentDepth + 1) $null = $node.Children.Add($child) } } if ($Objects) { foreach ($f in ($di.GetFiles("*.dat") + $di.GetFiles("*.json") | Sort-Object Name)) { $keyName = [System.IO.Path]::GetFileNameWithoutExtension($f.Name) $fNode = [PSCustomObject]@{ Name = $keyName Type = "Object" Path = "$relPath/$keyName" ObjectCount = 1 SizeBytes = $f.Length Depth = $CurrentDepth + 1 Children = [System.Collections.ArrayList]::new() _BucketName = $relPath _BucketKey = $keyName } $fNode.PSObject.TypeNames.Insert(0, "Buckets.Tree") $null = $node.Children.Add($fNode) } } $node } |