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

@@ -423,6 +423,12 @@ Function Get-GiteaChildItem {
.PARAMETER token .PARAMETER token
A personal access token for the Gitea server. 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 .EXAMPLE
# List items in the root directory of a repository # List items in the root directory of a repository
Get-GiteaChildItem -repoOwner "owner" -repoName "repo" -Path "" -token "your_token" Get-GiteaChildItem -repoOwner "owner" -repoName "repo" -Path "" -token "your_token"
@@ -432,6 +438,14 @@ Function Get-GiteaChildItem {
Get-GiteaChildItem -repoOwner "owner" -repoName "repo" -Path "docs" -token "your_token" | Get-GiteaChildItem -repoOwner "owner" -repoName "repo" -Path "docs" -token "your_token" |
Where-Object { $_.type -eq "file" } | Where-Object { $_.type -eq "file" } |
Get-GiteaFileContent -token "your_token" -decode 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()] [CmdletBinding()]
@@ -446,13 +460,13 @@ Function Get-GiteaChildItem {
[string[]]$Path, [string[]]$Path,
[Parameter(ValueFromPipelineByPropertyName)] [Parameter(ValueFromPipelineByPropertyName)]
[string]$branch = "main", [string]$branch = "main",
[string]$token [string]$token,
[switch]$Recurse,
[int]$Depth
) )
begin { begin {
# Initialize results array # 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 = @() $results = @()
# Use configuration if parameters aren't provided # Use configuration if parameters aren't provided
@@ -497,20 +511,29 @@ Function Get-GiteaChildItem {
# Load the GIT LFS configuration if needed # Load the GIT LFS configuration if needed
$lfsExtensions = Get-GiteaLFSConfiguration -giteaURL $giteaURL -repoOwner $repoOwner -repoName $repoName -token $token $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 { process {
$paths = $path $paths = $path
foreach ($path in $paths) { foreach ($path in $paths) {
Write-Verbose "Processing path: $path" 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" Write-Verbose "Encoded path: $encodedPath"
$url = "$giteaURL" $url = "$giteaURL"
$url += "/api/v1/repos" $url += "/api/v1/repos"
$url += "/$repoOwner" $url += "/$repoOwner"
$url += "/$repoName" $url += "/$repoName"
$url += "/contents" $url += "/contents"
$url += "/$encodedPath" # Only add the path component if it's not empty
if (-not [string]::IsNullOrWhiteSpace($normalizedPath)) {
$url += "/$encodedPath"
}
$url += "?ref=$branch" $url += "?ref=$branch"
Write-Verbose "URL: $url" Write-Verbose "URL: $url"
@@ -534,31 +557,130 @@ Function Get-GiteaChildItem {
$item.download_url = "$giteaURL/api/v1/repos/$repoOwner/$repoName/media/$($item.path)" $item.download_url = "$giteaURL/api/v1/repos/$repoOwner/$repoName/media/$($item.path)"
} }
$results += [PSCustomObject]@{ $itemObj = [PSCustomObject]@{
# Properties for direct pipeline binding with other functions in this module filePath = $item.path
filePath = $item.path # Maps to -filePath parameter Path = $item.path
Path = $item.path # Also include original name (alias) repoOwner = $repoOwner
repoOwner = $repoOwner # Maps to -repoOwner parameter repoName = $repoName
repoName = $repoName # Maps to -repoName parameter giteaURL = $giteaURL
giteaURL = $giteaURL # Maps to -giteaURL parameter downloadURL = $item.download_url
downloadURL = $item.download_url # Maps to -downloadURL parameter branch = $branch
branch = $branch # Maps to -branch parameter type = $item.type
# Additional useful properties
type = $item.type # 'file' or 'dir'
name = $item.name name = $item.name
size = $item.size size = $item.size
sha = $item.sha sha = $item.sha
Success = $true Success = $true
Error = $null 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 { 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]@{ $results += [PSCustomObject]@{
filePath = $path filePath = $normalizedPath
Path = $path Path = $normalizedPath
repoOwner = $repoOwner repoOwner = $repoOwner
repoName = $repoName repoName = $repoName
giteaURL = $giteaURL giteaURL = $giteaURL
@@ -570,6 +692,7 @@ Function Get-GiteaChildItem {
downloadURL = $null downloadURL = $null
Success = $false Success = $false
Error = $_.Exception.Message Error = $_.Exception.Message
Level = 0
} }
} }
} }