9 Commits
1.4.2 ... 1.5.4

Author SHA1 Message Date
08bf6a709c Bump module version to 1.5.4 and update Invoke-GiteaFileDownload to handle URL encoded characters in file names. Update pester tests to account for changes.
All checks were successful
Publish Powershell Module to Gitea Repository / test (push) Successful in 10s
Publish Powershell Module to Gitea Repository / deploy (push) Successful in 32s
2025-05-27 14:32:35 -04:00
b6a46b38bd Revert module version to 1.5.3 in the module manifest
All checks were successful
Publish Powershell Module to Gitea Repository / test (push) Successful in 10s
Publish Powershell Module to Gitea Repository / deploy (push) Successful in 33s
2025-05-27 14:23:10 -04:00
3f66adb4ca Bump module version to 1.5.5 and update Invoke-GiteaFileDownload to ensure URL encoded characters in the file name are properly replaced. 2025-05-27 14:22:51 -04:00
d647600568 Update Get-GiteaFileContent tests to use 'Result' for status reporting instead of 'Success'
All checks were successful
Publish Powershell Module to Gitea Repository / test (push) Successful in 10s
Publish Powershell Module to Gitea Repository / deploy (push) Successful in 32s
2025-05-27 13:27:38 -04:00
ed8f3ab02e Update pester tests
Some checks failed
Publish Powershell Module to Gitea Repository / test (push) Failing after 10s
Publish Powershell Module to Gitea Repository / deploy (push) Has been skipped
2025-05-27 13:23:37 -04:00
67d69c52e9 Bump module version to 1.5.0 and update Invoke-GiteaFileDownload and Get-GiteaChildItem functions to use 'Result' instead of 'Success' for status reporting, and add OverwriteByHash parameter for conditional file overwriting.
Some checks failed
Publish Powershell Module to Gitea Repository / test (push) Failing after 10s
Publish Powershell Module to Gitea Repository / deploy (push) Has been skipped
2025-05-27 13:14:28 -04:00
ed9ba80938 Bump module version to 1.4.5 and enhance Invoke-GiteaFileDownload to replace URL encoded characters in the file name
All checks were successful
Publish Powershell Module to Gitea Repository / test (push) Successful in 9s
Publish Powershell Module to Gitea Repository / deploy (push) Successful in 31s
2025-05-27 12:50:01 -04:00
edb1501f40 Bump module version to 1.4.4 and enhance Invoke-GiteaFileDownload to handle LFS file downloads with type inference and properly format file path based on API URL
All checks were successful
Publish Powershell Module to Gitea Repository / test (push) Successful in 10s
Publish Powershell Module to Gitea Repository / deploy (push) Successful in 31s
2025-05-27 12:38:58 -04:00
5854940f75 Bump module version to 1.4.3 and update download URL in Get-GiteaChildItem function to allow for getting LFS files from other branches
All checks were successful
Publish Powershell Module to Gitea Repository / test (push) Successful in 10s
Publish Powershell Module to Gitea Repository / deploy (push) Successful in 32s
2025-05-27 12:11:54 -04:00
4 changed files with 96 additions and 44 deletions

View File

@@ -12,7 +12,7 @@
RootModule = 'PS-GiteaUtilities.psm1' RootModule = 'PS-GiteaUtilities.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '1.4.2' ModuleVersion = '1.5.4'
# Supported PSEditions # Supported PSEditions
# CompatiblePSEditions = @() # CompatiblePSEditions = @()

View File

@@ -207,7 +207,7 @@ Function Get-GiteaFileContent {
Content = $content Content = $content
Size = $fileContent.size Size = $fileContent.size
SHA = $fileContent.sha SHA = $fileContent.sha
Success = $true Result = 'Success'
Error = $null Error = $null
} }
} }
@@ -218,7 +218,7 @@ Function Get-GiteaFileContent {
Content = $null Content = $null
Size = $null Size = $null
SHA = $null SHA = $null
Success = $false Result = 'Failure'
Error = $_.Exception.Message Error = $_.Exception.Message
} }
} }
@@ -337,6 +337,9 @@ Function Invoke-GiteaFileDownload {
If used with outputPath, treats the outputPath as the base directory to append the relative path to. If used with outputPath, treats the outputPath as the base directory to append the relative path to.
Cannot be used with outputName. Cannot be used with outputName.
.PARAMETER OverwriteByHash
A switch parameter to overwrite the file if it exists based on its hash.
.PARAMETER force .PARAMETER force
A switch parameter to force overwriting of an existing file at the output path. A switch parameter to force overwriting of an existing file at the output path.
@@ -344,6 +347,10 @@ Function Invoke-GiteaFileDownload {
The type of the item to download (file, dir, lfs). This parameter is typically used with pipeline input from Get-GiteaChildItem. The type of the item to download (file, dir, lfs). This parameter is typically used with pipeline input from Get-GiteaChildItem.
Directories will be skipped with a verbose message. Directories will be skipped with a verbose message.
.PARAMETER sha
The SHA of the file to download. This parameter is typically used with pipeline input from Get-GiteaChildItem.
Can be combined with OverwriteByHash to overwrite an existing file if the hashes do not match.
.EXAMPLE .EXAMPLE
# Example 1: Download a file to the current directory # Example 1: Download a file to the current directory
Invoke-GiteaFileDownload -downloadURL "https://gitea.example.com/api/v1/repos/owner/repo/raw/path/to/file.txt" -token "your_token" Invoke-GiteaFileDownload -downloadURL "https://gitea.example.com/api/v1/repos/owner/repo/raw/path/to/file.txt" -token "your_token"
@@ -375,9 +382,12 @@ Function Invoke-GiteaFileDownload {
[Parameter(ValueFromPipelineByPropertyName)] [Parameter(ValueFromPipelineByPropertyName)]
[string]$outputName, [string]$outputName,
[switch]$PreserveRelativePath, [switch]$PreserveRelativePath,
[switch]$OverwriteByHash,
[switch]$force, [switch]$force,
[Parameter(ValueFromPipelineByPropertyName)] [Parameter(ValueFromPipelineByPropertyName)]
[string]$type [string]$type,
[Parameter(ValueFromPipelineByPropertyName)]
[string]$sha
) )
begin { begin {
@@ -410,8 +420,12 @@ Function Invoke-GiteaFileDownload {
} }
process { process {
Write-Verbose "Type: $type" # If type is not provided, check for any hints for cases such as LFS where a type can be inferred and special handling is needed
If($downloadURL -match "/api/v1/repos/[^/]+/[^/]+/media/") {
$type = "lfs"
}
Write-Verbose "Type: $type"
# Handle the type parameter # Handle the type parameter
# Skip directories and provide a verbose message # Skip directories and provide a verbose message
@@ -420,8 +434,8 @@ Function Invoke-GiteaFileDownload {
return [PSCustomObject]@{ return [PSCustomObject]@{
SourceURL = $downloadURL SourceURL = $downloadURL
Type = $type Type = $type
Success = $true Result = 'Skipped'
Error = "Skipped - item is a directory" Error = $null
Timestamp = Get-Date Timestamp = Get-Date
FileSize = $null FileSize = $null
} }
@@ -434,7 +448,7 @@ Function Invoke-GiteaFileDownload {
return [PSCustomObject]@{ return [PSCustomObject]@{
SourceURL = $downloadURL SourceURL = $downloadURL
Type = $type Type = $type
Success = $false Result = 'Failure'
Error = $errorMsg Error = $errorMsg
Timestamp = Get-Date Timestamp = Get-Date
FileSize = $null FileSize = $null
@@ -447,10 +461,22 @@ Function Invoke-GiteaFileDownload {
# Separate the URL into its components: Gitea URL, Repo Owner, Repo Name, branch, file path, and file name # Separate the URL into its components: Gitea URL, Repo Owner, Repo Name, branch, file path, and file name
$uri = New-Object System.Uri($downloadURL) $uri = New-Object System.Uri($downloadURL)
$pathSegments = $uri.AbsolutePath.Trim('/').Split('/') $pathSegments = $uri.AbsolutePath.Trim('/').Split('/')
# Everything after the branch + 1 segment is considered the file path with the last segment being the file name If($type -eq "lfs") {
$branchIndex = [Array]::IndexOf($pathSegments, "branch") + 2 # Everything after the media segment is considered the file path with the last segment being the file name
$DownloadFilePath = $pathSegments[$branchIndex..($pathSegments.Length - 2)] -join '/' $branchIndex = [Array]::IndexOf($pathSegments, "media") + 1
$DownloadFileName = $pathSegments[-1] $DownloadFilePath = $pathSegments[$branchIndex..($pathSegments.Length - 2)] -join '/'
$DownloadFileName = $pathSegments[-1]
}
Else {
# Everything after the branch + 1 segment is considered the file path with the last segment being the file name
$branchIndex = [Array]::IndexOf($pathSegments, "branch") + 2
$DownloadFilePath = $pathSegments[$branchIndex..($pathSegments.Length - 2)] -join '/'
# Replace any URL encoded characters in the file name
$DownloadFileName = $pathSegments[-1]
}
$DownloadFilePath = [System.Uri]::UnescapeDataString($DownloadFilePath)
$DownloadFileName = [System.Uri]::UnescapeDataString($DownloadFileName)
if ($PreserveRelativePath -and $outputPath) { if ($PreserveRelativePath -and $outputPath) {
# If PreserveRelativePath is used, set up the directory structure # If PreserveRelativePath is used, set up the directory structure
@@ -497,17 +523,36 @@ Function Invoke-GiteaFileDownload {
Path = $fileOutputPath Path = $fileOutputPath
SourceURL = $downloadURL SourceURL = $downloadURL
Type = "file" Type = "file"
Success = $false Result = $null
Error = $null Error = $null
Timestamp = Get-Date Timestamp = Get-Date
FileSize = $null FileSize = $null
} }
if((Test-Path -Path $fileOutputPath -PathType Leaf) -and (-not $force)) { if((Test-Path -Path $fileOutputPath -PathType Leaf) -and (-not $force)) {
$errorMsg = "The file '$fileOutputPath' already exists. Use the -Force switch to overwrite the file." # Check if OverwriteByHash is set
Write-Error $errorMsg if ($OverwriteByHash) {
$result.Error = $errorMsg Write-Verbose "OverwriteByHash is set; checking file hash for existing file: $fileOutputPath"
return $result $existingFileHash = (Get-FileHash -Path $fileOutputPath -Algorithm SHA256).Hash
$downloadFileHash = $sha
if ($existingFileHash -eq $downloadFileHash) {
Write-Host "The file '$fileOutputPath' already exists and hashes match. Skipping download."
$result.Result = 'Skipped'
return $result
}
else {
Write-Host "The file '$fileOutputPath' already exists but hashes do not match and OverwriteByHash is set; overwriting file."
}
}
else {
$result.Result = 'Skipped'
$errorMsg = "The file '$fileOutputPath' already exists. Use the -Force switch to overwrite the file."
Write-Error $errorMsg
$result.Error = $errorMsg
return $result
}
} }
try { try {
@@ -532,10 +577,11 @@ Function Invoke-GiteaFileDownload {
$result.FileSize = $fileInfo.Length $result.FileSize = $fileInfo.Length
} }
$result.Success = $true $result.Result = 'Success'
return $result return $result
} }
catch { catch {
$result.Result = 'Failure'
$errorMsg = "Failed to download file from Gitea: $_" $errorMsg = "Failed to download file from Gitea: $_"
Write-Error $errorMsg Write-Error $errorMsg
$result.Error = $errorMsg $result.Error = $errorMsg
@@ -732,7 +778,7 @@ Function Get-GiteaChildItem {
$item.size = [long]$matches[1] $item.size = [long]$matches[1]
} }
# Set the download URL to the media endpoint for LFS files to download the actual file # Set the download URL to the media endpoint for LFS files to download the actual file
$item.download_url = "$giteaURL/api/v1/repos/$repoOwner/$repoName/media/$($item.path)" $item.download_url = "$giteaURL/api/v1/repos/$repoOwner/$repoName/media/$($item.path)?ref=$branch"
} }
$itemObj = [PSCustomObject]@{ $itemObj = [PSCustomObject]@{
@@ -742,7 +788,7 @@ Function Get-GiteaChildItem {
size = $item.size size = $item.size
sha = $item.sha sha = $item.sha
downloadURL = $item.download_url downloadURL = $item.download_url
Success = $true Result = 'Success'
Error = $null Error = $null
Level = 0 Level = 0
} }
@@ -825,7 +871,7 @@ Function Get-GiteaChildItem {
size = $subItem.size size = $subItem.size
sha = $subItem.sha sha = $subItem.sha
downloadURL = $subItem.download_url downloadURL = $subItem.download_url
Success = $true Result = 'Success'
Error = $null Error = $null
Level = $currentLevel Level = $currentLevel
} }
@@ -872,7 +918,7 @@ Function Get-GiteaChildItem {
size = $null size = $null
sha = $null sha = $null
downloadURL = $null downloadURL = $null
Success = $false Result = 'Failure'
Error = $_.Exception.Message Error = $_.Exception.Message
Level = 0 Level = 0
} }

View File

@@ -21,7 +21,7 @@ Describe 'Get-GiteaFileContent' {
$result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'README.md' -token 'abc123' $result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'README.md' -token 'abc123'
$result | Should -Not -BeNullOrEmpty $result | Should -Not -BeNullOrEmpty
$result.Success | Should -Be $true $result.Result | Should -Be 'Success'
$result.Content | Should -Be ([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('Hello World'))) $result.Content | Should -Be ([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('Hello World')))
} }
@@ -29,7 +29,7 @@ Describe 'Get-GiteaFileContent' {
$result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'README.md' -token 'abc123' -decode $result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'README.md' -token 'abc123' -decode
$result | Should -Not -BeNullOrEmpty $result | Should -Not -BeNullOrEmpty
$result.Success | Should -Be $true $result.Result | Should -Be 'Success'
$result.Content | Should -Be 'Hello World' $result.Content | Should -Be 'Hello World'
} }
} }
@@ -73,7 +73,7 @@ Describe 'Get-GiteaFileContent' {
It 'Should capture error and mark result as unsuccessful' { It 'Should capture error and mark result as unsuccessful' {
$result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'badfile.ps1' -token 'abc123' $result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'badfile.ps1' -token 'abc123'
$result.Success | Should -Be $false $result.Result | Should -Be 'Failure'
$result.Error | Should -Match 'API call failed' $result.Error | Should -Match 'API call failed'
} }
} }
@@ -103,7 +103,7 @@ Describe 'Get-GiteaFileContent' {
$result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'testfile.txt' -token 'abc123' $result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'testfile.txt' -token 'abc123'
$result | Should -Not -BeNullOrEmpty $result | Should -Not -BeNullOrEmpty
$result.Success | Should -Be $true $result.Result | Should -Be 'Success'
$result.Content | Should -Be ([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('Hello from API!'))) $result.Content | Should -Be ([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('Hello from API!')))
} }
@@ -111,7 +111,7 @@ Describe 'Get-GiteaFileContent' {
$result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'testfile.txt' -token 'abc123' -decode $result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'testfile.txt' -token 'abc123' -decode
$result | Should -Not -BeNullOrEmpty $result | Should -Not -BeNullOrEmpty
$result.Success | Should -Be $true $result.Result | Should -Be 'Success'
$result.Content | Should -Be 'Hello from API!' $result.Content | Should -Be 'Hello from API!'
} }
} }

View File

@@ -46,51 +46,59 @@ Describe 'Invoke-GiteaFileDownload' {
Context 'When all parameters are valid' { Context 'When all parameters are valid' {
It 'Should download a file successfully' { It 'Should download a file successfully' {
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/file.txt' -token 'abc123' $result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/test/example/raw/branch/dev/path/to/file.txt' -token 'abc123'
$result | Should -Not -BeNullOrEmpty $result | Should -Not -BeNullOrEmpty
$result.Success | Should -Be $true $result.Result | Should -Be 'Success'
$result.Path | Should -Match 'file\.txt$' $result.Path | Should -Match 'file\.txt$'
} }
} }
Context 'When specifying an outputPath' { Context 'When specifying an outputPath' {
It 'Should create a path based on outputPath' { It 'Should create a path based on outputPath' {
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/file.txt' ` $result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/test/example/raw/branch/dev/path/to/file.txt' `
-outputPath 'docs/manual/' -token 'abc123' -outputPath 'docs/manual/' -token 'abc123'
$result.Path | Should -Match 'docs[\\/]+manual[\\/]+file\.txt$' $result.Path | Should -Match 'docs[\\/]+manual[\\/]+file\.txt$'
$result.Success | Should -Be $true $result.Result | Should -Be 'Success'
} }
} }
Context 'When specifying an outputName' { Context 'When specifying an outputName' {
It 'Should download file and name it based on outputName' { It 'Should download file and name it based on outputName' {
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/file.txt' ` $result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/test/example/raw/branch/dev/path/to/file.txt' `
-outputName 'newfile.txt' -token 'abc123' -outputName 'newfile.txt' -token 'abc123'
$result.Path | Should -Match 'newfile\.txt$' $result.Path | Should -Match 'newfile\.txt$'
$result.Success | Should -Be $true $result.Result | Should -Be 'Success'
} }
} }
Context 'When specifying an outputName and outputPath' { Context 'When specifying an outputName and outputPath' {
It 'Should download file and name it based on outputName' { It 'Should download file and name it based on outputName' {
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/file.txt' ` $result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/test/example/raw/branch/dev/path/to/file.txt' `
-outputPath 'docs/manual/' -outputName 'newfile.txt' -token 'abc123' -outputPath 'docs/manual/' -outputName 'newfile.txt' -token 'abc123'
$result.Path | Should -Match 'docs[\\/]+manual[\\/]+newfile\.txt$' $result.Path | Should -Match 'docs[\\/]+manual[\\/]+newfile\.txt$'
$result.Success | Should -Be $true $result.Result | Should -Be 'Success'
} }
} }
Context 'When using -PreserveRelativePath' { Context 'When using -PreserveRelativePath' {
It 'Should preserve the relative path structure' { It 'Should preserve the relative path structure' {
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/file.txt' ` $result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/test/example/raw/branch/dev/path/to/file.txt' `
-PreserveRelativePath -token 'abc123' -PreserveRelativePath -token 'abc123'
$result.Path | Should -Match 'path[\\/]+to[\\/]+file\.txt$' $result.Path | Should -Match 'path[\\/]+to[\\/]+file\.txt$'
$result.Success | Should -Be $true $result.Result | Should -Be 'Success'
}
It 'Should ensure the outputPath does not contain any URL encoding' {
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/test/example/raw/branch/dev/Client%20Files/Certificates/file name.txt' `
-PreserveRelativePath -token 'abc123'
$result.Path | Should -Match 'Client[ ]Files[\\/]+Certificates[\\/]+file name\.txt$'
$result.Result | Should -Be 'Success'
} }
} }
@@ -98,8 +106,7 @@ Describe 'Invoke-GiteaFileDownload' {
It 'Should skip items with type = dir' { It 'Should skip items with type = dir' {
$result = Invoke-GiteaFileDownload -outputPath 'docs/' -type 'dir' -token 'abc123' $result = Invoke-GiteaFileDownload -outputPath 'docs/' -type 'dir' -token 'abc123'
$result.Success | Should -Be $true $result.Result | Should -Be 'Skipped'
$result.Error | Should -Match 'Skipped'
} }
} }
@@ -114,10 +121,9 @@ Describe 'Invoke-GiteaFileDownload' {
} }
It 'Should not overwrite existing file without Force' { It 'Should not overwrite existing file without Force' {
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/existingfile.txt' -token 'abc123' $result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/test/example/raw/branch/dev/path/to/existingfile.txt' -token 'abc123'
$result.Success | Should -Be $false $result.Result | Should -Be 'Skipped'
$result.Error | Should -Match 'already exists'
} }
} }
@@ -143,9 +149,9 @@ Describe 'Invoke-GiteaFileDownload' {
} }
It 'Should capture error and mark download as failed' { It 'Should capture error and mark download as failed' {
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/badfile.txt' -token 'abc123' $result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/test/example/raw/branch/dev/path/to/badfile.txt' -token 'abc123'
$result.Success | Should -Be $false $result.Result | Should -Be 'Failure'
$result.Error | Should -Match 'Failed to download' $result.Error | Should -Match 'Failed to download'
} }
} }