Enhance Get-GiteaChildItem function with recursion and depth parameters for improved directory listing

This commit is contained in:
2025-04-24 15:57:17 -04:00
parent 305ec3c2fb
commit d8dfb1d1fe

View File

@@ -422,6 +422,12 @@ Function Get-GiteaChildItem {
.PARAMETER token
A personal access token for the Gitea server.
.PARAMETER Recurse
Recursively lists items in all subdirectories.
.PARAMETER Depth
Specifies the number of subdirectory levels to include in the recursion. Default is unlimited if Recurse is specified.
.EXAMPLE
# List items in the root directory of a repository
@@ -432,6 +438,14 @@ Function Get-GiteaChildItem {
Get-GiteaChildItem -repoOwner "owner" -repoName "repo" -Path "docs" -token "your_token" |
Where-Object { $_.type -eq "file" } |
Get-GiteaFileContent -token "your_token" -decode
.EXAMPLE
# Recursively list all items in a repository
Get-GiteaChildItem -repoOwner "owner" -repoName "repo" -Path "src" -Recurse -token "your_token"
.EXAMPLE
# List items with a maximum depth of 2 subdirectories
Get-GiteaChildItem -repoOwner "owner" -repoName "repo" -Path "src" -Recurse -Depth 2 -token "your_token"
#>
[CmdletBinding()]
@@ -446,13 +460,13 @@ Function Get-GiteaChildItem {
[string[]]$Path,
[Parameter(ValueFromPipelineByPropertyName)]
[string]$branch = "main",
[string]$token
[string]$token,
[switch]$Recurse,
[int]$Depth
)
begin {
# Initialize results array
# This is used to store the results of the API calls later
# It is initialized here to avoid re-initializing it in the process block
$results = @()
# Use configuration if parameters aren't provided
@@ -497,20 +511,29 @@ Function Get-GiteaChildItem {
# Load the GIT LFS configuration if needed
$lfsExtensions = Get-GiteaLFSConfiguration -giteaURL $giteaURL -repoOwner $repoOwner -repoName $repoName -token $token
# Initialize a queue for directories to process when using recursion
$directoryQueue = [System.Collections.Queue]::new()
}
process {
$paths = $path
foreach ($path in $paths) {
Write-Verbose "Processing path: $path"
$encodedPath = [System.Uri]::EscapeDataString($path)
# Normalize the path format - replace backslashes with forward slashes and trim trailing slashes
$normalizedPath = $path -replace '\\', '/' -replace '/$', ''
$encodedPath = [System.Uri]::EscapeDataString($normalizedPath)
Write-Verbose "Normalized path: $normalizedPath"
Write-Verbose "Encoded path: $encodedPath"
$url = "$giteaURL"
$url += "/api/v1/repos"
$url += "/$repoOwner"
$url += "/$repoName"
$url += "/contents"
$url += "/$encodedPath"
# Only add the path component if it's not empty
if (-not [string]::IsNullOrWhiteSpace($normalizedPath)) {
$url += "/$encodedPath"
}
$url += "?ref=$branch"
Write-Verbose "URL: $url"
@@ -534,31 +557,130 @@ Function Get-GiteaChildItem {
$item.download_url = "$giteaURL/api/v1/repos/$repoOwner/$repoName/media/$($item.path)"
}
$results += [PSCustomObject]@{
# Properties for direct pipeline binding with other functions in this module
filePath = $item.path # Maps to -filePath parameter
Path = $item.path # Also include original name (alias)
repoOwner = $repoOwner # Maps to -repoOwner parameter
repoName = $repoName # Maps to -repoName parameter
giteaURL = $giteaURL # Maps to -giteaURL parameter
downloadURL = $item.download_url # Maps to -downloadURL parameter
branch = $branch # Maps to -branch parameter
# Additional useful properties
type = $item.type # 'file' or 'dir'
$itemObj = [PSCustomObject]@{
filePath = $item.path
Path = $item.path
repoOwner = $repoOwner
repoName = $repoName
giteaURL = $giteaURL
downloadURL = $item.download_url
branch = $branch
type = $item.type
name = $item.name
size = $item.size
sha = $item.sha
Success = $true
Error = $null
Level = 0
}
$results += $itemObj
# If the item is a directory and we're recursing, add it to the queue
if ($Recurse -and $item.type -eq 'dir') {
$directoryQueue.Enqueue(@{
Path = $item.path
Level = 1
})
}
}
# Process the directory queue if recursion is enabled
if ($Recurse) {
while ($directoryQueue.Count -gt 0) {
$currentDir = $directoryQueue.Dequeue()
$currentPath = $currentDir.Path
$currentLevel = $currentDir.Level
# Check depth limit if specified
if ($PSBoundParameters.ContainsKey('Depth') -and $currentLevel -gt $Depth) {
continue
}
Write-Verbose "Recursing into: $currentPath (Level: $currentLevel)"
# Normalize the path format for consistent handling
$normalizedSubPath = $currentPath -replace '\\', '/' -replace '/$', ''
$encodedSubPath = [System.Uri]::EscapeDataString($normalizedSubPath)
Write-Verbose "Normalized sub path: $normalizedSubPath"
Write-Verbose "Encoded sub path: $encodedSubPath"
# Fix the URL construction for subdirectories
$subUrl = "$giteaURL/api/v1/repos/$repoOwner/$repoName/contents/$encodedSubPath"
# Add the branch reference separately to avoid issues
$subUrl += "?ref=$branch"
Write-Verbose "Sub URL: $subUrl"
try {
$subResponse = Invoke-RestMethod -Uri $subUrl -Method Get -Headers $headers -ErrorAction Stop
$subItems = if ($subResponse -is [array]) { $subResponse } else { @($subResponse) }
foreach ($subItem in $subItems) {
# Check if the name ends with any of the LFS extensions
$isLFS = $false
foreach ($ext in $lfsExtensions) {
if ($subItem.name.EndsWith($ext, [System.StringComparison]::InvariantCultureIgnoreCase)) {
$isLFS = $true
break
}
}
if ($isLFS) {
$subItem.type = "lfs"
$subItem.download_url = "$giteaURL/api/v1/repos/$repoOwner/$repoName/media/$($subItem.path)"
}
$subItemObj = [PSCustomObject]@{
filePath = $subItem.path
Path = $subItem.path
repoOwner = $repoOwner
repoName = $repoName
giteaURL = $giteaURL
downloadURL = $subItem.download_url
branch = $branch
type = $subItem.type
name = $subItem.name
size = $subItem.size
sha = $subItem.sha
Success = $true
Error = $null
Level = $currentLevel
}
$results += $subItemObj
# If the subitem is a directory, add it to the queue for further processing
if ($subItem.type -eq 'dir') {
$nextLevel = $currentLevel + 1
# Only add to queue if we haven't hit our depth limit
if (-not $PSBoundParameters.ContainsKey('Depth') -or $nextLevel -le $Depth) {
$directoryQueue.Enqueue(@{
Path = $subItem.path
Level = $nextLevel
})
}
}
}
}
catch {
$errorDetails = if ($_.ErrorDetails) {
try { $_.ErrorDetails.Message | ConvertFrom-Json -ErrorAction SilentlyContinue } catch { $_.ErrorDetails.Message }
} else { $null }
Write-Error "Failed to recursively retrieve path '$normalizedSubPath' from Gitea: $($_.Exception.Message)`n$($errorDetails | ConvertTo-Json -Depth 1 -Compress)"
}
}
}
}
catch {
Write-Error "Failed to retrieve '$path' from Gitea: $_"
$errorDetails = if ($_.ErrorDetails) {
try { $_.ErrorDetails.Message | ConvertFrom-Json -ErrorAction SilentlyContinue } catch { $_.ErrorDetails.Message }
} else { $null }
Write-Error "Failed to retrieve '$normalizedPath' from Gitea: $($_.Exception.Message)`n$($errorDetails | ConvertTo-Json -Depth 1 -Compress)"
$results += [PSCustomObject]@{
filePath = $path
Path = $path
filePath = $normalizedPath
Path = $normalizedPath
repoOwner = $repoOwner
repoName = $repoName
giteaURL = $giteaURL
@@ -570,6 +692,7 @@ Function Get-GiteaChildItem {
downloadURL = $null
Success = $false
Error = $_.Exception.Message
Level = 0
}
}
}