From 4a512dd40456c7582e9668e3e33e230e8d251554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Mon, 27 Oct 2025 03:45:49 -0700 Subject: [PATCH 01/17] refactor(database): cache databaseRoot to avoid calling so much integration --- private/database/databaseV2.ps1 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/private/database/databaseV2.ps1 b/private/database/databaseV2.ps1 index 706c692..f38e477 100644 --- a/private/database/databaseV2.ps1 +++ b/private/database/databaseV2.ps1 @@ -14,7 +14,7 @@ function Reset-DatabaseStore{ [CmdletBinding()] param() - $databaseRoot = Invoke-MyCommand -Command GetDatabaseStorePath + $databaseRoot = Get-DatabaseStore Microsoft.PowerShell.Management\Remove-Item -Path $databaseRoot -Recurse -Force -ErrorAction SilentlyContinue @@ -26,9 +26,13 @@ function Get-DatabaseStore{ [CmdletBinding()] param() - $databaseRoot = Invoke-MyCommand -Command GetDatabaseStorePath + if($script:databaseRoot){ + return $script:databaseRoot + } - return $databaseRoot + $script:databaseRoot = Invoke-MyCommand -Command GetDatabaseStorePath + + return $script:databaseRoot } Export-ModuleMember -Function Get-DatabaseStore @@ -79,7 +83,7 @@ function Get-DatabaseFile{ [Parameter(Position = 0)][string]$Key ) - $databaseRoot = Invoke-MyCommand -Command GetDatabaseStorePath + $databaseRoot = Get-DatabaseStore $path = $databaseRoot | Join-Path -ChildPath "$Key.json" From 65d715530d92e2edf3962b840c3e64c7d74a8f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Mon, 27 Oct 2025 03:56:48 -0700 Subject: [PATCH 02/17] fix(database): allow force on Get-DatabaseStore for reset --- private/database/databaseV2.ps1 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/private/database/databaseV2.ps1 b/private/database/databaseV2.ps1 index f38e477..2197b10 100644 --- a/private/database/databaseV2.ps1 +++ b/private/database/databaseV2.ps1 @@ -14,25 +14,25 @@ function Reset-DatabaseStore{ [CmdletBinding()] param() - $databaseRoot = Get-DatabaseStore + $databaseRoot = Get-DatabaseStore -Force - Microsoft.PowerShell.Management\Remove-Item -Path $databaseRoot -Recurse -Force -ErrorAction SilentlyContinue + Microsoft.PowerShell.Management\Remove-Item -Path $databaseRoot -Recurse -Force -ErrorAction SilentlyContinue - New-Item -Path $databaseRoot -ItemType Directory + New-Item -Path $databaseRoot -ItemType Directory } Export-ModuleMember -Function Reset-DatabaseStore function Get-DatabaseStore{ [CmdletBinding()] - param() - - if($script:databaseRoot){ - return $script:databaseRoot - } + param( + [switch] $Force + ) + if ($Force -or -Not $script:databaseRoot) { $script:databaseRoot = Invoke-MyCommand -Command GetDatabaseStorePath + } - return $script:databaseRoot + return $script:databaseRoot } Export-ModuleMember -Function Get-DatabaseStore From b021f1e086e0e0327b5a757d0792e918477bb11b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Mon, 27 Oct 2025 03:57:07 -0700 Subject: [PATCH 03/17] style(database): format code for consistency and readability --- private/database/databaseV2.ps1 | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/private/database/databaseV2.ps1 b/private/database/databaseV2.ps1 index 2197b10..0dea988 100644 --- a/private/database/databaseV2.ps1 +++ b/private/database/databaseV2.ps1 @@ -6,11 +6,11 @@ Set-MyInvokeCommandAlias -Alias GetDatabaseStorePath -Command "Invoke-ProjectHel $DATABASE_ROOT = [System.Environment]::GetFolderPath('UserProfile') | Join-Path -ChildPath ".helpers" -AdditionalChildPath $MODULE_NAME, "databaseCache" # Create the database root if it does not exist -if(-Not (Test-Path $DATABASE_ROOT)){ +if (-Not (Test-Path $DATABASE_ROOT)) { New-Item -Path $DATABASE_ROOT -ItemType Directory } -function Reset-DatabaseStore{ +function Reset-DatabaseStore { [CmdletBinding()] param() @@ -22,7 +22,7 @@ function Reset-DatabaseStore{ } Export-ModuleMember -Function Reset-DatabaseStore -function Get-DatabaseStore{ +function Get-DatabaseStore { [CmdletBinding()] param( [switch] $Force @@ -36,15 +36,15 @@ function Get-DatabaseStore{ } Export-ModuleMember -Function Get-DatabaseStore -function Get-Database{ +function Get-Database { [CmdletBinding()] param( [Parameter(Position = 0)][string]$Key ) - $path = Get-DatabaseFile $Key + $path = Get-DatabaseFile $Key - if(-Not (Test-Path $path)){ + if (-Not (Test-Path $path)) { return $null } @@ -53,17 +53,17 @@ function Get-Database{ return $ret } -function Reset-Database{ +function Reset-Database { [CmdletBinding()] param( [Parameter(Position = 0)][string]$Key ) - $path = Get-DatabaseFile -Key $Key + $path = Get-DatabaseFile -Key $Key Microsoft.PowerShell.Management\Remove-Item -Path $path -Force -ErrorAction SilentlyContinue return } -function Save-Database{ +function Save-Database { [CmdletBinding()] param( [Parameter(Position = 0)][string]$Key, @@ -77,7 +77,7 @@ function Save-Database{ $Database | ConvertTo-Json -Depth 10 | Set-Content $path } -function Get-DatabaseFile{ +function Get-DatabaseFile { [CmdletBinding()] param( [Parameter(Position = 0)][string]$Key @@ -90,7 +90,7 @@ function Get-DatabaseFile{ return $path } -function Invoke-ProjectHelperGetDatabaseStorePath{ +function Invoke-ProjectHelperGetDatabaseStorePath { [CmdletBinding()] param() From 8f5917c0d6f55de6da408a6d60c64d7a151cdabc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Mon, 27 Oct 2025 04:38:19 -0700 Subject: [PATCH 04/17] refactor(test): update Get-ProjectItemList references to Get-ProjectItems --- .../interactive_test/get-project-paging.test.ps1 | 2 +- .../project_item.searchprojectitem.test.ps1 | 2 +- Test/public/project_item.test.ps1 | 8 ++++---- Test/public/project_item_list.test.ps1 | 16 ++++++++-------- Test/public/project_items_staged.test.ps1 | 1 - .../sync-ProjectItemsBetweenProjects.ps1 | 4 ++-- .../update-ProjectItemsStatusOnDueDate.ps1 | 4 ++-- .../update-ProjectItemsWithIntegration.ps1 | 4 ++-- public/items/project_item_List.ps1 | 2 +- 9 files changed, 21 insertions(+), 22 deletions(-) diff --git a/Test/public/interactive_test/get-project-paging.test.ps1 b/Test/public/interactive_test/get-project-paging.test.ps1 index 35bb4ba..f527d90 100644 --- a/Test/public/interactive_test/get-project-paging.test.ps1 +++ b/Test/public/interactive_test/get-project-paging.test.ps1 @@ -11,7 +11,7 @@ function Test_GetProject_Paging_SUCCESS{ Assert-NotNull -Presented $result - $presented = Get-ProjectItemList -Owner $owner -ProjectNumber $projectNumber + $presented = Get-ProjectItems -Owner $owner -ProjectNumber $projectNumber -IncludeDone $fields = Get-ProjectFields -Owner $owner -ProjectNumber $projectNumber Assert-Count -Expected 332 -Presented $presented diff --git a/Test/public/project_item.searchprojectitem.test.ps1 b/Test/public/project_item.searchprojectitem.test.ps1 index 0660de0..79bd576 100644 --- a/Test/public/project_item.searchprojectitem.test.ps1 +++ b/Test/public/project_item.searchprojectitem.test.ps1 @@ -44,7 +44,7 @@ function Test_SearchProjectItem_PassThru_SUCCESS { Assert-Count -Expected $expected -Presented $shown # Compare one item type difference - Assert-IsTrue -Condition ($raw[0] -is [hashtable]) + Assert-IsTrue -Condition ($raw[0] -is [pscustomobject]) Assert-IsTrue -Condition ($shown[0] -is [pscustomobject]) Assert-Count -Expected $attributes.Count -Presented $($shown[0].PSObject.Properties.Name) diff --git a/Test/public/project_item.test.ps1 b/Test/public/project_item.test.ps1 index d44590c..0de8d61 100644 --- a/Test/public/project_item.test.ps1 +++ b/Test/public/project_item.test.ps1 @@ -295,7 +295,7 @@ function Test_EditProjectItems_Direct{ function Test_UpdateProjectDatabase_Fail_With_Staged{ # When changes are staged list update should fail. - # As Update-ProjectDatabase is a private function, we will test it through the public function Get-ProjectItemList with Force + # As Update-ProjectDatabase is a private function, we will test it through the public function Get-ProjectItems with Force Reset-InvokeCommandMock Mock_DatabaseRoot @@ -309,7 +309,7 @@ function Test_UpdateProjectDatabase_Fail_With_Staged{ MockCall_GetItem -ItemId $itemId # Act empty as their is nothing staged yet - $result = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber -Force + $result = Get-ProjectItems -Owner $Owner -ProjectNumber $ProjectNumber -Force -IncludeDone Assert-Count -Expected $itemsCount -Presented $result # arrange modifyt to add staged @@ -322,7 +322,7 @@ function Test_UpdateProjectDatabase_Fail_With_Staged{ # This call should fail as there are staged changes Start-MyTranscript - $result = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber -Force + $result = Get-ProjectItems -Owner $Owner -ProjectNumber $ProjectNumber -Force -IncludeDone $tt = Stop-MyTranscript Assert-IsNull -Object $result @@ -333,7 +333,7 @@ function Test_UpdateProjectDatabase_Fail_With_Staged{ Reset-ProjectItemStaged -Owner $owner -ProjectNumber $projectNumber $result = Get-ProjectItemStaged -Owner $owner -ProjectNumber $projectNumber Assert-Count -Expected 0 -Presented $result.Keys - $result = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber -Force + $result = Get-ProjectItems -Owner $Owner -ProjectNumber $ProjectNumber -Force -IncludeDone Assert-Count -Expected $itemsCount -Presented $result } diff --git a/Test/public/project_item_list.test.ps1 b/Test/public/project_item_list.test.ps1 index caed1f2..eadc631 100644 --- a/Test/public/project_item_list.test.ps1 +++ b/Test/public/project_item_list.test.ps1 @@ -10,11 +10,11 @@ function Test_GetProjetItemList_SUCCESS{ MockCall_GetProject_700 # Act - $result = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber + $result = Get-ProjectItems -Owner $Owner -ProjectNumber $ProjectNumber -IncludeDone Assert-Count -Expected $itemsCount -Presented $result - $randomItem = $result.$($i.Id) + $randomItem = $result | Where-Object {$_.id -eq $i.id} Assert-AreEqual -Presented $randomItem.Title -Expected "Issue for development" Assert-AreEqual -Presented $randomItem.Body -Expected "Body of issue for development" @@ -45,7 +45,7 @@ function Test_GetProjetItemList_SUCCESS{ Mock_DatabaseRoot -NotReset # Can call without mock because it will use the database information - $result = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber + $result = Get-ProjectItems -Owner $Owner -ProjectNumber $ProjectNumber -IncludeDone Assert-Count -Expected $itemsCount -Presented $result } @@ -65,7 +65,7 @@ function Test_GetProjetItemList_FAIL{ # Run the command Start-MyTranscript - $result = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber + $result = Get-ProjectItems -Owner $Owner -ProjectNumber $ProjectNumber -IncludeDone $tt = Stop-MyTranscript # Capture the standard output @@ -86,13 +86,13 @@ function Test_ProjectItemList_ExcludeDone{ MockCall_GetProject_700 - $result = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber + $result = Get-ProjectItems -Owner $Owner -ProjectNumber $ProjectNumber -IncludeDone - Assert-AreEqual -Expected $itemsCount -Presented $result.Keys.Count + Assert-AreEqual -Expected $itemsCount -Presented $result.Count - $result = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber -ExcludeDone + $result = Get-ProjectItems -Owner $Owner -ProjectNumber $ProjectNumber - Assert-AreEqual -Expected ($itemsCount - $itemsDone) -Presented $result.Keys.Count + Assert-AreEqual -Expected ($itemsCount - $itemsDone) -Presented $result.Count } diff --git a/Test/public/project_items_staged.test.ps1 b/Test/public/project_items_staged.test.ps1 index f030702..5ffc7a1 100644 --- a/Test/public/project_items_staged.test.ps1 +++ b/Test/public/project_items_staged.test.ps1 @@ -885,7 +885,6 @@ function Test_TestProjectItemStaged { # Project is cached MockCall_GetProject_700 -Cache - $null = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber $result = Test-ProjectItemStaged -Owner $Owner -ProjectNumber $ProjectNumber Assert-IsFalse -Condition $result diff --git a/public/integrations/sync-ProjectItemsBetweenProjects.ps1 b/public/integrations/sync-ProjectItemsBetweenProjects.ps1 index ce12709..552598e 100644 --- a/public/integrations/sync-ProjectItemsBetweenProjects.ps1 +++ b/public/integrations/sync-ProjectItemsBetweenProjects.ps1 @@ -66,10 +66,10 @@ function Update-ProjectItemsBetweenProjects { $FieldsList = $sourceProject.fields.Values.name # Get source project items - $sourceItems = Get-ProjectItemList -Owner $SourceOwner -ProjectNumber $SourceProjectNumber -ExcludeDone:$(-not $IncludeDoneItems) + $sourceItems = Get-ProjectItems -Owner $SourceOwner -ProjectNumber $SourceProjectNumber -IncludeDone:$IncludeDoneItems # Process each item in the source project - foreach($sourceItem in $sourceItems.Values){ + foreach($sourceItem in $sourceItems){ # Find matching item in destination project # Use URL # By the moment we are not going to sync Drafts as they belong to single project and therefore no matching is possible diff --git a/public/integrations/update-ProjectItemsStatusOnDueDate.ps1 b/public/integrations/update-ProjectItemsStatusOnDueDate.ps1 index 3160d1f..4cf4d3f 100644 --- a/public/integrations/update-ProjectItemsStatusOnDueDate.ps1 +++ b/public/integrations/update-ProjectItemsStatusOnDueDate.ps1 @@ -138,9 +138,9 @@ function Invoke-ProjectInjectionOnDueDate { ($Owner,$ProjectNumber) = Get-OwnerAndProjectNumber -Owner $Owner -ProjectNumber $ProjectNumber if([string]::IsNullOrWhiteSpace($owner) -or [string]::IsNullOrWhiteSpace($ProjectNumber)){ "Owner and ProjectNumber are required" | Write-MyError; return $null} - $items = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber -ExcludeDone:$(-Not $IncludeDoneItems) + $items = Get-ProjectItems -Owner $Owner -ProjectNumber $ProjectNumber -IncludeDone:$IncludeDoneItems - foreach($item in $items.Values){ + foreach($item in $items){ function EditItem($FieldName,$Value){ $params = @{ diff --git a/public/integrations/update-ProjectItemsWithIntegration.ps1 b/public/integrations/update-ProjectItemsWithIntegration.ps1 index 213ad26..21aa94f 100644 --- a/public/integrations/update-ProjectItemsWithIntegration.ps1 +++ b/public/integrations/update-ProjectItemsWithIntegration.ps1 @@ -48,9 +48,9 @@ function Invoke-ProjectInjectionWithIntegration{ ($Owner,$ProjectNumber) = Get-OwnerAndProjectNumber -Owner $Owner -ProjectNumber $ProjectNumber if([string]::IsNullOrWhiteSpace($owner) -or [string]::IsNullOrWhiteSpace($ProjectNumber)){ "Owner and ProjectNumber are required" | Write-MyError; return $null} - $items = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber -ExcludeDone:$(-not $IncludeDoneItems) + $items = Get-ProjectItems -Owner $Owner -ProjectNumber $ProjectNumber -IncludeDone:$IncludeDoneItems - foreach($item in $items.Values){ + foreach($item in $items){ # Skip if the item does not have the integration field if(-not $item.$IntegrationField){ diff --git a/public/items/project_item_List.ps1 b/public/items/project_item_List.ps1 index fa84d69..51892e5 100644 --- a/public/items/project_item_List.ps1 +++ b/public/items/project_item_List.ps1 @@ -38,7 +38,7 @@ Gets all items from project 1 excluding those with status "Done". function Get-ProjectItemList{ [CmdletBinding()] [OutputType([string[]])] - [Obsolete("Get-ProjectItemList is deprecated. Use Get-ProjectItems instead.")] + [Obsolete("Use Get-ProjectItems instead.")] param( [Parameter(Position = 0)] [string]$Owner, [Parameter(Position = 1)] [string]$ProjectNumber, From c83289e65b223b6aaa6865d0c7e6e6a5fcdab797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Mon, 27 Oct 2025 05:08:18 -0700 Subject: [PATCH 05/17] fix(test): update error message for unsaved changes in project item retrieval --- Test/public/project_item.test.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Test/public/project_item.test.ps1 b/Test/public/project_item.test.ps1 index 0de8d61..2dcf364 100644 --- a/Test/public/project_item.test.ps1 +++ b/Test/public/project_item.test.ps1 @@ -326,7 +326,7 @@ function Test_UpdateProjectDatabase_Fail_With_Staged{ $tt = Stop-MyTranscript Assert-IsNull -Object $result - $message = "Error: Can not get item list with Force [True]; There are unsaved changes. Restore changes with Reset-ProjectItemStaged or sync projects with Sync-ProjectItemStaged first and try again" + $message = "Error: Failed to get project [octodemo/700]: There are unsaved changes. Restore changes with Reset-ProjectItemStaged or sync projects with Sync-ProjectItemStaged first and try again" Assert-Contains -Expected $message -Presented $tt # Reset the staged changes From ca150a83021b0e4533966014bb5fbc7b43ca7f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Mon, 27 Oct 2025 05:09:08 -0700 Subject: [PATCH 06/17] refactor(project): update Search-ProjectItem to Get-ProjectItems with improved error handling and option for hashtable return --- public/items/project_item.ps1 | 39 +++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/public/items/project_item.ps1 b/public/items/project_item.ps1 index 262ced6..208811a 100644 --- a/public/items/project_item.ps1 +++ b/public/items/project_item.ps1 @@ -142,7 +142,8 @@ function Search-ProjectItem { ($Owner, $ProjectNumber) = Get-OwnerAndProjectNumber -Owner $Owner -ProjectNumber $ProjectNumber if ([string]::IsNullOrWhiteSpace($owner) -or [string]::IsNullOrWhiteSpace($ProjectNumber)) { "Owner and ProjectNumber are required" | Write-MyError; return $null } - $items = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber -Force:$Force -ExcludeDone:$(-not $IncludeDone) + # Get items as hashtable for later queries + $items = Get-ProjectItems -Owner $Owner -ProjectNumber $ProjectNumber -Force:$Force -IncludeDone:$IncludeDone -AsHashtable # return if #items is null if ($null -eq $items) { return $null } @@ -224,20 +225,46 @@ function Get-ProjectItems { [Parameter()][string]$Owner, [Parameter()][string]$ProjectNumber, [Parameter()][switch]$IncludeDone, - [Parameter()][switch]$Force + [Parameter()][switch]$Force, + [Parameter()][switch]$AsHashtable ) ($Owner, $ProjectNumber) = Get-OwnerAndProjectNumber -Owner $Owner -ProjectNumber $ProjectNumber if ([string]::IsNullOrWhiteSpace($owner) -or [string]::IsNullOrWhiteSpace($ProjectNumber)) { "Owner and ProjectNumber are required" | Write-MyError; return $null } - $items = Get-ProjectItemList -Owner $Owner -ProjectNumber $ProjectNumber -Force:$Force -ExcludeDone:$(-not $IncludeDone) + try { + $db = Get-Project -Owner $Owner -ProjectNumber $ProjectNumber -Force:$Force + } + catch { + "Failed to get project [$owner/$ProjectNumber]: $_" | Write-MyError + return + } + + # Check if $db is null + if($null -eq $db){ "Project not found. Check owner and projectnumber" | Write-MyError ; return } + + $itemKeys = $db.items.Keys + + $items = $itemKeys | ForEach-Object { Get-Item $db $_ } + + # exclude done items if needed + if(! $IncludeDone){ + $items = $items | Where-Object { $_.Status -ne "Done" } + } # return if #items is null - if ($null -eq $items) { return $null } + if ($null -eq $items) { return } - $ret = @($items.Values | ForEach-Object { + if($AsHashtable){ + $ret = New-HashTable + foreach($item in $items){ + $ret[$item.id] = $item + } + } else { + $ret = @($items | ForEach-Object { [PSCustomObject]$_ - } ) + }) + } return $ret From a53de42f9230741686f98be5de98463b32bbc662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Thu, 30 Oct 2025 18:58:48 -0700 Subject: [PATCH 07/17] refactor(item): remove Get-ProjectItemList --- public/items/project_item_List.ps1 | 93 ------------------------------ 1 file changed, 93 deletions(-) delete mode 100644 public/items/project_item_List.ps1 diff --git a/public/items/project_item_List.ps1 b/public/items/project_item_List.ps1 deleted file mode 100644 index 51892e5..0000000 --- a/public/items/project_item_List.ps1 +++ /dev/null @@ -1,93 +0,0 @@ - - -<# -.SYNOPSIS -Gets a list of project items from a GitHub project. - -.DESCRIPTION -Retrieves all items from a GitHub project and returns them as a hashtable with ItemId as the key. -Can optionally exclude items with status "Done". - -.PARAMETER Owner -The owner of the GitHub repository containing the project. - -.PARAMETER ProjectNumber -The project number in the repository. - -.PARAMETER Project -An existing project object. If provided, Owner and ProjectNumber are not required. - -.PARAMETER ExcludeDone -When specified, excludes items with status "Done" from the results. - -.PARAMETER Force -Forces a refresh of the project data from GitHub. - -.OUTPUTS -System.Collections.Hashtable -Returns a hashtable where keys are ItemIds and values are project item objects. - -.EXAMPLE -Get-ProjectItemList -Owner "octocat" -ProjectNumber "1" -Gets all items from project 1 in the octocat organization. - -.EXAMPLE -Get-ProjectItemList -Owner "octocat" -ProjectNumber "1" -ExcludeDone -Gets all items from project 1 excluding those with status "Done". -#> -function Get-ProjectItemList{ - [CmdletBinding()] - [OutputType([string[]])] - [Obsolete("Use Get-ProjectItems instead.")] - param( - [Parameter(Position = 0)] [string]$Owner, - [Parameter(Position = 1)] [string]$ProjectNumber, - [Parameter()][object]$Project, - [Parameter()][switch]$ExcludeDone, - [Parameter()][switch]$Force - ) - - try { - # If Project is not provided, get it from Owner and ProjectNumber - if(-not $Project){ - ($Owner,$ProjectNumber) = Get-OwnerAndProjectNumber -Owner $Owner -ProjectNumber $ProjectNumber - if([string]::IsNullOrWhiteSpace($owner) -or [string]::IsNullOrWhiteSpace($ProjectNumber)){ "Owner and ProjectNumber are required" | Write-MyError; return $null} - - $db = Get-Project -Owner $Owner -ProjectNumber $ProjectNumber -Force:$Force - } else { - $db = $Project - } - - # Check if $db is null - if($null -eq $db){ - "Project not found. Check owner and projectnumber" | Write-MyError - return $null - } - - #exclude done items if ExcludeDone is set - if($ExcludeDone){ - $keys = $db.items.Keys | Where-Object { $db.items.$_.Status -ne "Done"} - } else { - $keys = $db.items.Keys - } - - # Create a hashtable with ItemId as the key - $ret = New-HashTable - foreach ($key in $keys) { - # ">> Getting item with ItemId [$key] from project [$ProjectNumber] for owner [$Owner]" | Write-MyHost - # $item = Get-ProjectItem -ItemId $key -Owner $Owner -ProjectNumber $ProjectNumber - $item = Get-Item $db $key - # "<< Get-ProjectItem returned: $($item | Out-String)" | Write-MyHost - - if ($null -ne $item) { - $ret[$key] = $item - } - } - - return $ret - } catch { - "Can not get item list with Force [$Force]; $_" | Write-MyError - } - -} Export-ModuleMember -Function Get-ProjectItemList - From 3f69a636ee54273d7cab172570f4078df5d2d7e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Thu, 30 Oct 2025 19:09:37 -0700 Subject: [PATCH 08/17] refactor(include): sync with include modules --- Test/include/invokeCommand.mock.ps1 | 29 +++++++++++++++++++++++++++++ include/MyWrite.ps1 | 2 ++ include/callAPI.ps1 | 3 ++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Test/include/invokeCommand.mock.ps1 b/Test/include/invokeCommand.mock.ps1 index a109768..d5fae35 100644 --- a/Test/include/invokeCommand.mock.ps1 +++ b/Test/include/invokeCommand.mock.ps1 @@ -3,6 +3,9 @@ # # This includes help commands to mock invokes in a test module # +# Set $env:TraceInvokeMockFilePath to trave Invoke dependencies +# "traceInvoke.log" | %{touch $_ ; $env:TraceInvokeMockFilePath = $_ | Resolve-Path} +# # THIS INCLUDE REQURED module.helper.ps1 if(-not $MODULE_NAME){ throw "Missing MODULE_NAME varaible initialization. Check for module.helerp.ps1 file." } if(-not $MODULE_ROOT_PATH){ throw "Missing MODULE_ROOT_PATH varaible initialization. Check for module.helerp.ps1 file." } @@ -14,6 +17,28 @@ $MOCK_PATH = $testRootPath | Join-Path -ChildPath 'private' -AdditionalChildPath $MODULE_INVOKATION_TAG = "$($MODULE_NAME)Module" $MODULE_INVOKATION_TAG_MOCK = "$($MODULE_INVOKATION_TAG)_Mock" +function Trace-InvokeCommandAlias{ + [CmdletBinding()] + param( + [Parameter(Mandatory,Position=0)][string]$Alias + ) + + $filePath = $env:TraceInvokeMockFilePath + + if(! $filePath){ return } + + if(! (Test-Path $filePath)) {return} + + $content = Get-Content $filePath + + $content = $content ?? @() + + if($content.Contains($Alias)) { return} + + $alias | Out-File $filePath -Append + +} + function Set-InvokeCommandMock{ [CmdletBinding()] param( @@ -22,6 +47,8 @@ function Set-InvokeCommandMock{ ) InvokeHelper\Set-InvokeCommandAlias -Alias $Alias -Command $Command -Tag $MODULE_INVOKATION_TAG_MOCK + + Trace-InvokeCommandAlias $alias } function Reset-InvokeCommandMock{ @@ -258,3 +285,5 @@ function Assert-MockFileNotfound{ + + diff --git a/include/MyWrite.ps1 b/include/MyWrite.ps1 index e35d900..84c7833 100644 --- a/include/MyWrite.ps1 +++ b/include/MyWrite.ps1 @@ -206,3 +206,5 @@ function Get-ObjetString { + + diff --git a/include/callAPI.ps1 b/include/callAPI.ps1 index bae65a1..3f910b7 100644 --- a/include/callAPI.ps1 +++ b/include/callAPI.ps1 @@ -227,4 +227,5 @@ function writedebug{ process{ Write-MyDebug $Message -Section "api" } -} \ No newline at end of file +} + From d71c084b8c9f363217c0a62c5ec7862d7a5f1a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Fri, 31 Oct 2025 00:58:52 -0700 Subject: [PATCH 09/17] faet(test_loging): add traceInvoke and mockfiles --- Test/include/InvokeMockList.ps1 | 48 +++++++++ Test/include/invokeCommand.mock.ps1 | 21 +++- Test/mockfiles.log | 154 ++++++++++++++++++++++++++++ Test/traceInvoke.log | 68 ++++++++++++ 4 files changed, 286 insertions(+), 5 deletions(-) create mode 100644 Test/include/InvokeMockList.ps1 create mode 100644 Test/mockfiles.log create mode 100644 Test/traceInvoke.log diff --git a/Test/include/InvokeMockList.ps1 b/Test/include/InvokeMockList.ps1 new file mode 100644 index 0000000..3223779 --- /dev/null +++ b/Test/include/InvokeMockList.ps1 @@ -0,0 +1,48 @@ + +$MockCommandFile = $testRootPath | Join-Path -ChildPath "mockfiles.log" + +function Trace-MockCommandFile{ + [CmdletBinding()] + param( + [string] $Command, + [string] $FileName + ) + + # read content + $content = readMockCommandFile + + # Check that the entry is already there + $result = $content | Where-Object{$_.command -eq $command} + if($null -ne $result) {return} + + # add entry + $new = @{ + Command = $command + FileName = $fileName + } + + $ret = @() + $ret += $content + $ret += $new + + # Save list + writeMockCommandFile -Content $ret +} + +function readMockCommandFile{ + $ret = Get-Content -Path $MockCommandFile | ConvertFrom-Json + + # return an empty aray if content does not exists + $ret = $ret ?? @() + + return $ret +} + +function writeMockCommandFile($Content){ + + $list = $Content | ConvertTo-Json + + $sorted = $list | Sort-Object fileName + + $sorted | Out-File -FilePath $MockCommandFile +} \ No newline at end of file diff --git a/Test/include/invokeCommand.mock.ps1 b/Test/include/invokeCommand.mock.ps1 index d5fae35..8aaaf93 100644 --- a/Test/include/invokeCommand.mock.ps1 +++ b/Test/include/invokeCommand.mock.ps1 @@ -3,8 +3,8 @@ # # This includes help commands to mock invokes in a test module # -# Set $env:TraceInvokeMockFilePath to trave Invoke dependencies -# "traceInvoke.log" | %{touch $_ ; $env:TraceInvokeMockFilePath = $_ | Resolve-Path} +# Set $env:TraceInvokeMock to trave Invoke dependencies +# "traceInvoke.log" | %{touch $_ ; $env:TraceInvokeMock = $_ | Resolve-Path} # # THIS INCLUDE REQURED module.helper.ps1 if(-not $MODULE_NAME){ throw "Missing MODULE_NAME varaible initialization. Check for module.helerp.ps1 file." } @@ -17,17 +17,19 @@ $MOCK_PATH = $testRootPath | Join-Path -ChildPath 'private' -AdditionalChildPath $MODULE_INVOKATION_TAG = "$($MODULE_NAME)Module" $MODULE_INVOKATION_TAG_MOCK = "$($MODULE_INVOKATION_TAG)_Mock" +$TraceInvokeMock = $testRootPath | Join-Path -ChildPath "traceInvoke.log" + function Trace-InvokeCommandAlias{ [CmdletBinding()] param( [Parameter(Mandatory,Position=0)][string]$Alias ) - $filePath = $env:TraceInvokeMockFilePath + $filePath = $TraceInvokeMock if(! $filePath){ return } - if(! (Test-Path $filePath)) {return} + # if(! (Test-Path $filePath)) {return} $content = Get-Content $filePath @@ -35,7 +37,7 @@ function Trace-InvokeCommandAlias{ if($content.Contains($Alias)) { return} - $alias | Out-File $filePath -Append + $alias | Out-File $filePath -Append -Force } @@ -81,6 +83,8 @@ function MockCall{ Assert-MockFileNotfound $fileName + Trace-MockCommandFile -Command $command -Filename $filename + Set-InvokeCommandMock -Alias $command -Command "Get-MockFileContent -filename $filename" } @@ -92,6 +96,8 @@ function MockCallAsync{ Assert-MockFileNotfound $fileName + Trace-MockCommandFile -Command $command -Filename $filename + $moduleTest = $PSScriptRoot | Split-Path -Parent | Convert-Path Set-InvokeCommandMock -Alias $command -Command "Import-Module $moduleTest ; Get-MockFileContent -filename $filename" @@ -106,6 +112,9 @@ function MockCallJson{ ) Assert-MockFileNotfound $fileName + + Trace-MockCommandFile -Command $command -Filename $filename + $asHashTableString = $AsHashtable ? '$true' : '$false' $commandstr ='Get-MockFileContentJson -filename {filename} -AsHashtable:{asHashTableString}' @@ -124,6 +133,8 @@ function MockCallJsonAsync{ Assert-MockFileNotfound $fileName + Trace-MockCommandFile -Command $command -Filename $filename + $moduleTest = $PSScriptRoot | Split-Path -Parent | Convert-Path Set-InvokeCommandMock -Alias $command -Command "Import-Module $moduleTest ; Get-MockFileContentJson -filename $filename" diff --git a/Test/mockfiles.log b/Test/mockfiles.log new file mode 100644 index 0000000..f4b8fdd --- /dev/null +++ b/Test/mockfiles.log @@ -0,0 +1,154 @@ +[ + { + "FileName": "invoke-GitHubOrgProjectWithFields-octodemo-700-skipitems.json", + "Command": "Invoke-GitHubOrgProjectWithFields -Owner octodemo -ProjectNumber 700 -afterFields \"\" -afterItems \"\" -firstItems 0" + }, + { + "FileName": "invoke-addcomment-I_kwDOPrRnkc7KkwSq.json", + "Command": "Invoke-AddComment -SubjectId I_kwDOPrRnkc7KkwSq -Comment \"sample comment 1\"" + }, + { + "FileName": "invoke-getitem-PVTI_lADOAlIw4c4BCe3Vzgeio4o.json", + "Command": "Invoke-GetItem -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o" + }, + { + "FileName": "invoke-getitem-PVTI_lADOAlIw4c4BCe3VzgeioBY.json", + "Command": "Invoke-GetItem -ItemId PVTI_lADOAlIw4c4BCe3VzgeioBY" + }, + { + "FileName": "invoke-addcomment-PR_kwDOPrRnkc6nndcE.json", + "Command": "Invoke-AddComment -SubjectId PR_kwDOPrRnkc6nndcE -Comment \"sample comment 1\"" + }, + { + "FileName": "invoke-GitHubOrgProjectWithFields-octodemo-700.json", + "Command": "Invoke-GitHubOrgProjectWithFields -Owner octodemo -ProjectNumber 700 -afterFields \"\" -afterItems \"\"" + }, + { + "FileName": "invoke-addSubIssue-I_kwDOPrRnkc7KkwSq-9.json", + "Command": "Invoke-AddSubIssue -IssueId I_kwDOPrRnkc7KkwSq -SubIssueUrl https://github.com/octodemo/rulasg-dev-1/issues/9 -ReplaceParent False" + }, + { + "FileName": "invoke-addSubIssue-I_kwDOPrRnkc7KkwSq-5.json", + "Command": "Invoke-AddSubIssue -IssueId I_kwDOPrRnkc7KkwSq -SubIssueUrl https://github.com/octodemo/rulasg-dev-1/issues/5 -ReplaceParent False" + }, + { + "FileName": "invoke-GitHubOrgProjectWithFields-octodemo-625.2-skipitems.json", + "Command": "Invoke-GitHubOrgProjectWithFields -Owner octodemo -ProjectNumber 625 -afterFields \"\" -afterItems \"\" -firstItems 0" + }, + { + "FileName": "invoke-getitem-PVTI_lADOAlIw4c4A0Lf4zgYNTc0.json", + "Command": "Invoke-GetItem -itemid PVTI_lADOAlIw4c4A0Lf4zgYNTc0" + }, + { + "FileName": "invoke-addcomment-I_kwDOPrRnkc7KkwSq.json", + "Command": "Invoke-AddComment -SubjectId I_kwDOPrRnkc7KkwSq -Comment \"New comment\"" + }, + { + "FileName": "invoke-addcomment-I_kwDOPrRnkc7KkwSq.json", + "Command": "Invoke-AddComment -SubjectId I_kwDOPrRnkc7KkwSq -Comment \"Another comment2\"" + }, + { + "FileName": "findprojectempty.json", + "Command": "Invoke-FindProject -Owner github -Pattern \"emptylistpattern\" -firstProject 100 -afterProject \"\"" + }, + { + "FileName": "findprojectwithlist.json", + "Command": "Invoke-FindProject -Owner github -Pattern \"kk\" -firstProject 100 -afterProject \"\"" + }, + { + "FileName": "invoke-getitem-PVTI_lADNJr_OADU3Ys4GAgVO.json", + "Command": "Invoke-GetItem -itemid PVTI_lADNJr_OADU3Ys4GAgVO" + }, + { + "FileName": "projectV2-skipitems.json", + "Command": "Invoke-GitHubOrgProjectWithFields -Owner SomeOrg -ProjectNumber 164 -afterFields \"\" -afterItems \"\" -firstItems 0" + }, + { + "FileName": "invoke-getitem-id1.json", + "Command": "Invoke-GetItem -itemid id1" + }, + { + "FileName": "invoke-getitem-id2.json", + "Command": "Invoke-GetItem -itemid id2" + }, + { + "FileName": "invoke-GetIssueOrPullRequest-26.json", + "Command": "Invoke-GetIssueOrPullRequest -Url https://github.com/octodemo/rulasg-dev-1/issues/26" + }, + { + "FileName": "invoke-getitem-PVTI_lADOAlIw4c4BCe3Vzgeiodc-updated.json", + "Command": "Invoke-GetItem -itemid PVTI_lADOAlIw4c4BCe3Vzgeiodc" + }, + { + "FileName": "invoke-getitem-PVTI_lADOAlIw4c4BCe3Vzgec8p8.json", + "Command": "Invoke-GetItem -ItemId PVTI_lADOAlIw4c4BCe3Vzgec8p8" + }, + { + "FileName": "invoke-repository-rulasg-dev-1.json", + "Command": "Invoke-Repository -Owner octodemo -Name rulasg-dev-1" + }, + { + "FileName": "invoke-getitem-PVTI_lADOAlIw4c4A0Lf4zgYNTxI.json", + "Command": "Invoke-GetItem -itemid PVTI_lADOAlIw4c4A0Lf4zgYNTxI" + }, + { + "FileName": "invoke-createDraftItem.json", + "Command": "Invoke-CreateDraftItem -ProjectId PVT_kwDOAlIw4c4BCe3V -Title \"DraftIssue created for test \" -Body \"Body of draftissue\"" + }, + { + "FileName": "invoke-createissue-R_kgDOPrRnkQ.json", + "Command": "Invoke-CreateIssue -RepositoryId R_kgDOPrRnkQ -Title \"Random value title\" -Body \"Random value body\"" + }, + { + "FileName": "invoke-getissueorpullrequest-46.json", + "Command": "Invoke-GetIssueOrPullRequest -Url https://github.com/octodemo/rulasg-dev-1/issues/46" + }, + { + "FileName": "invoke-additemtoproject-PVT_kwDOAlIw4c4BCe3V-I_kwDOPrRnkc7T2Al2.json", + "Command": "Invoke-AddItemToProject -ProjectId PVT_kwDOAlIw4c4BCe3V -ContentId I_kwDOPrRnkc7T2Al2" + }, + { + "FileName": "invoke-removeitemfromproject-PVT_kwDOAlIw4c4BCe3V-PVTI_lADOAlIw4c4BCe3VzggVZH8.json", + "Command": "Invoke-RemoveItemFromProject -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3VzggVZH8" + }, + { + "FileName": "invoke-removeissue-any.json", + "Command": "Invoke-RemoveIssue -IssueId I_kwDOPrRnkc7T2Al2" + }, + { + "FileName": "projectV2.json", + "Command": "Invoke-GitHubOrgProjectWithFields -Owner SomeOrg -ProjectNumber 164 -afterFields \"\" -afterItems \"\"" + }, + { + "FileName": "invoke-addcomment-I_kwDOPrRnkc7KkwSq.json", + "Command": "Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-AddComment -SubjectId I_kwDOPrRnkc7KkwSq -Comment \"new comment added\"" + }, + { + "FileName": "invoke-addcomment-PR_kwDOPrRnkc6nndcE.json", + "Command": "Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-AddComment -SubjectId PR_kwDOPrRnkc6nndcE -Comment \"new comment added\"" + }, + { + "FileName": "invoke-clearProjectV2ItemFieldValue-PVT_kwDOAlIw4c4BCe3V-PVTI_lADOAlIw4c4BCe3Vzgeio4o-PVTF_lADOAlIw4c4BCe3Vzg0rhko.json", + "Command": "Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-GitHubClearItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhko" + }, + { + "FileName": "invoke-clearProjectV2ItemFieldValue-PVT_kwDOAlIw4c4BCe3V-PVTI_lADOAlIw4c4BCe3Vzgeio4o-PVTSSF_lADOAlIw4c4BCe3Vzg0rhno.json", + "Command": "Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-GitHubClearItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o -FieldId PVTSSF_lADOAlIw4c4BCe3Vzg0rhno" + }, + { + "FileName": "invoke-clearProjectV2ItemFieldValue-PVT_kwDOAlIw4c4BCe3V-PVTI_lADOAlIw4c4BCe3Vzgeio4o-PVTF_lADOAlIw4c4BCe3Vzg0rhko.json", + "Command": "Invoke-GitHubClearItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhko" + }, + { + "FileName": "invoke-clearProjectV2ItemFieldValue-PVT_kwDOAlIw4c4BCe3V-PVTI_lADOAlIw4c4BCe3Vzgeio4o-PVTSSF_lADOAlIw4c4BCe3Vzg0rhno.json", + "Command": "Invoke-GitHubClearItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o -FieldId PVTSSF_lADOAlIw4c4BCe3Vzg0rhno" + }, + { + "FileName": "invoke-GitHubOrgProjectWithFields-octodemo-625.json", + "Command": "Invoke-GitHubOrgProjectWithFields -Owner octodemo -ProjectNumber 625 -afterFields \"\" -afterItems \"\"" + }, + { + "FileName": "invoke-GitHubOrgProjectWithFields-octodemo-626.json", + "Command": "Invoke-GitHubOrgProjectWithFields -Owner octodemo -ProjectNumber 626 -afterFields \"\" -afterItems \"\"" + } +] diff --git a/Test/traceInvoke.log b/Test/traceInvoke.log new file mode 100644 index 0000000..a97125a --- /dev/null +++ b/Test/traceInvoke.log @@ -0,0 +1,68 @@ +Invoke-ProjectHelperGetDatabaseStorePath +Invoke-GitHubOrgProjectWithFields -Owner octodemo -ProjectNumber 700 -afterFields "" -afterItems "" -firstItems 0 +Invoke-GetItem -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o +Invoke-AddComment -SubjectId I_kwDOPrRnkc7KkwSq -Comment "sample comment 1" +Invoke-GetItem -ItemId PVTI_lADOAlIw4c4BCe3VzgeioBY +Invoke-AddComment -SubjectId PR_kwDOPrRnkc6nndcE -Comment "sample comment 1" +Invoke-GitHubOrgProjectWithFields -Owner octodemo -ProjectNumber 700 -afterFields "" -afterItems "" +Invoke-AddSubIssue -IssueId I_kwDOPrRnkc7KkwSq -SubIssueUrl https://github.com/octodemo/rulasg-dev-1/issues/9 -ReplaceParent False +Invoke-AddSubIssue -IssueId I_kwDOPrRnkc7KkwSq -SubIssueUrl https://github.com/octodemo/rulasg-dev-1/issues/5 -ReplaceParent False +Invoke-GetItem -itemid PVTI_lADOAlIw4c4BCe3Vzgeio4o +Invoke-GitHubOrgProjectWithFields -Owner octodemo -ProjectNumber 625 -afterFields "" -afterItems "" -firstItems 0 +Invoke-GetItem -itemid PVTI_lADOAlIw4c4A0Lf4zgYNTc0 +Invoke-AddComment -SubjectId I_kwDOPrRnkc7KkwSq -Comment "New comment" +Invoke-AddComment -SubjectId I_kwDOPrRnkc7KkwSq -Comment "Another comment2" +Invoke-FindProject -Owner github -Pattern "emptylistpattern" -firstProject 100 -afterProject "" +Invoke-FindProject -Owner github -Pattern "kk" -firstProject 100 -afterProject "" +Invoke-GetItem -itemid PVTI_lADNJr_OADU3Ys4GAgVO +Invoke-GitHubOrgProjectWithFields -Owner SomeOrg -ProjectNumber 164 -afterFields "" -afterItems "" -firstItems 0 +Invoke-GetItem -itemid id1 +Invoke-GetItem -itemid id2 +Invoke-GetIssueOrPullRequest -Url https://github.com/octodemo/rulasg-dev-1/issues/26 +Invoke-GetItem -ItemId PVTI_lADOAlIw4c4BCe3Vzgeiodc +Invoke-GetItem -itemid PVTI_lADOAlIw4c4BCe3Vzgeiodc +Invoke-GetItem -ItemId PVTI_lADOAlIw4c4BCe3Vzgec8p8 +Invoke-GitHubOrgProjectWithFields -Owner SomeOrg -ProjectNumber 164 -afterFields "" -afterItems "" +Invoke-Repository -Owner octodemo -Name rulasg-dev-1 +Invoke-GetItem -itemid PVTI_lADOAlIw4c4A0Lf4zgYNTxI +Invoke-CreateDraftItem -ProjectId PVT_kwDOAlIw4c4BCe3V -Title "DraftIssue created for test " -Body "Body of draftissue" +Invoke-CreateIssue -RepositoryId R_kgDOPrRnkQ -Title "Random value title" -Body "Random value body" +Invoke-GetIssueOrPullRequest -Url https://github.com/octodemo/rulasg-dev-1/issues/46 +Invoke-AddItemToProject -ProjectId PVT_kwDOAlIw4c4BCe3V -ContentId I_kwDOPrRnkc7T2Al2 +"Sample Text for Editor" | code -w - +Invoke-RemoveItemFromProject -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3VzggVZH8 +Invoke-RemoveIssue -IssueId I_kwDOPrRnkc7T2Al2 +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-GitHubUpdateItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeiodc -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhko -Value "new value of the comment 10" -Type text +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-UpdateDraftIssue -Id DI_lADOAlIw4c4BCe3VzgJwmkk -Title "new value of the title" -Body "" +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-UpdateDraftIssue -Id DI_lADOAlIw4c4BCe3VzgJwmkk -Title "" -Body "new value of the body" +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-GitHubUpdateItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhko -Value "new value of the comment 10" -Type text +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-UpdateIssue -Id I_kwDOPrRnkc7KkwSq -Title "new value of the title" -Body "" +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-UpdateIssue -Id I_kwDOPrRnkc7KkwSq -Title "" -Body "new value of the body" +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-AddComment -SubjectId I_kwDOPrRnkc7KkwSq -Comment "new comment added" +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-GitHubUpdateItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3VzgeioBY -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhko -Value "new value of the comment 10" -Type text +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-UpdatePullRequest -Id PR_kwDOPrRnkc6nndcE -Title "new value of the title" -Body "" +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-UpdatePullRequest -Id PR_kwDOPrRnkc6nndcE -Title "" -Body "new value of the body" +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-AddComment -SubjectId PR_kwDOPrRnkc6nndcE -Comment "new comment added" +Invoke-GitHubUpdateItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeiodc -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhko -Value "new value of the comment 10" -Type text +Invoke-UpdateDraftIssue -Id DI_lADOAlIw4c4BCe3VzgJwmkk -Title "new value of the title" -Body "" +Invoke-UpdateDraftIssue -Id DI_lADOAlIw4c4BCe3VzgJwmkk -Title "" -Body "new value of the body" +Invoke-GitHubUpdateItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhko -Value "new value of the comment 10" -Type text +Invoke-UpdateIssue -Id I_kwDOPrRnkc7KkwSq -Title "new value of the title" -Body "" +Invoke-UpdateIssue -Id I_kwDOPrRnkc7KkwSq -Title "" -Body "new value of the body" +Invoke-GitHubUpdateItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3VzgeioBY -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhko -Value "new value of the comment 10" -Type text +Invoke-UpdatePullRequest -Id PR_kwDOPrRnkc6nndcE -Title "new value of the title" -Body "" +Invoke-UpdatePullRequest -Id PR_kwDOPrRnkc6nndcE -Title "" -Body "new value of the body" +Invoke-GitHubUpdateItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3VzgeioBY -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhlU -Value "2021-01-10" -Type date +Invoke-GitHubUpdateItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3VzgeioBY -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhjU -Value "10.1" -Type number +Invoke-GitHubUpdateItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3VzgeioBY -FieldId PVTSSF_lADOAlIw4c4BCe3Vzg0rhno -Value "cd02c585" -Type singleSelectOptionId +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-GitHubClearItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhko +Import-Module /Users/rulasg/code/ProjectHelper ; Invoke-GitHubClearItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o -FieldId PVTSSF_lADOAlIw4c4BCe3Vzg0rhno +Invoke-GitHubClearItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhko +Invoke-GitHubClearItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o -FieldId PVTSSF_lADOAlIw4c4BCe3Vzg0rhno +Invoke-GitHubUpdateItemValues -ProjectId PVT_kwDOAlIw4c4BCe3V -ItemId PVTI_lADOAlIw4c4BCe3Vzgeio4o -FieldId PVTF_lADOAlIw4c4BCe3Vzg0rhko -Value "some value" -Type text +Invoke-GitHubOrgProjectWithFields -Owner octodemo -ProjectNumber 625 -afterFields "" -afterItems "" +Invoke-GitHubOrgProjectWithFields -Owner octodemo -ProjectNumber 626 -afterFields "" -afterItems "" +Get-Date -Format yyyy-MM-dd +Invoke-ProjectInjectionFunctions +Get-SfAccount "https://some.com/1234/viuew" +Get-SfAccount "https://some.com/4321/viuew" From a8337440f5d64c492ad73fa2658a467c393fefb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Wed, 5 Nov 2025 20:08:45 +0100 Subject: [PATCH 10/17] style(invokeCommand): improve debug message formatting --- helper/invokeCommand.helper.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/invokeCommand.helper.ps1 b/helper/invokeCommand.helper.ps1 index 6c09d61..5a08f46 100644 --- a/helper/invokeCommand.helper.ps1 +++ b/helper/invokeCommand.helper.ps1 @@ -28,7 +28,7 @@ function Invoke-MyCommand{ [Parameter(Position=1)][hashtable]$Parameters ) - Write-MyDebug "[invoke] $Command" $Parameters + Write-MyDebug "invoke" $Command $Parameters return InvokeHelper\Invoke-MyCommand -Command $Command -Parameters $Parameters } From 737faf206de15f433800710dbecef6cb26123d55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Wed, 5 Nov 2025 20:08:54 +0100 Subject: [PATCH 11/17] refactor(MyWrite): rename functions for clarity and consistency --- include/MyWrite.ps1 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/MyWrite.ps1 b/include/MyWrite.ps1 index 84c7833..fb019ef 100644 --- a/include/MyWrite.ps1 +++ b/include/MyWrite.ps1 @@ -112,7 +112,7 @@ function Test-MyVerbose { return $trace } -function Set-ModuleNameVerbose{ +function Enable-ModuleNameVerbose{ param( [Parameter(Position = 0)][string]$section ) @@ -126,16 +126,16 @@ function Set-ModuleNameVerbose{ $moduleDebugVarName = $MODULE_NAME + "_VERBOSE" [System.Environment]::SetEnvironmentVariable($moduleDebugVarName, $flag) } -Rename-Item -path Function:Set-ModuleNameVerbose -NewName "Set-$($MODULE_NAME)Verbose" +Rename-Item -path Function:Enable-ModuleNameVerbose -NewName "Set-$($MODULE_NAME)Verbose" Export-ModuleMember -Function "Set-$($MODULE_NAME)Verbose" -function Clear-ModuleNameVerbose{ +function Disable-ModuleNameVerbose{ param() $moduleDebugVarName = $MODULE_NAME + "_VERBOSE" [System.Environment]::SetEnvironmentVariable($moduleDebugVarName, $null) } -Rename-Item -path Function:Clear-ModuleNameVerbose -NewName "Clear-$($MODULE_NAME)Verbose" +Rename-Item -path Function:Disable-ModuleNameVerbose -NewName "Clear-$($MODULE_NAME)Verbose" Export-ModuleMember -Function "Clear-$($MODULE_NAME)Verbose" function Test-MyDebug { @@ -159,7 +159,7 @@ function Test-MyDebug { return $trace } -function Set-ModuleNameDebug{ +function Enable-ModuleNameDebug{ param( [Parameter(Position = 0)][string]$section ) @@ -173,17 +173,17 @@ function Set-ModuleNameDebug{ $moduleDebugVarName = $MODULE_NAME + "_DEBUG" [System.Environment]::SetEnvironmentVariable($moduleDebugVarName, $flag) } -Rename-Item -path Function:Set-ModuleNameDebug -NewName "Set-$($MODULE_NAME)Debug" -Export-ModuleMember -Function "Set-$($MODULE_NAME)Debug" +Rename-Item -path Function:Enable-ModuleNameDebug -NewName "Enable-$($MODULE_NAME)Debug" +Export-ModuleMember -Function "Enable-$($MODULE_NAME)Debug" -function Clear-ModuleNameDebug{ +function Disable-ModuleNameDebug { param() $moduleDebugVarName = $MODULE_NAME + "_DEBUG" [System.Environment]::SetEnvironmentVariable($moduleDebugVarName, $null) } -Rename-Item -path Function:Clear-ModuleNameDebug -NewName "Clear-$($MODULE_NAME)Debug" -Export-ModuleMember -Function "Clear-$($MODULE_NAME)Debug" +Rename-Item -path Function:Disable-ModuleNameDebug -NewName "Disable-$($MODULE_NAME)Debug" +Export-ModuleMember -Function "Disable-$($MODULE_NAME)Debug" function Get-ObjetString { param( From ad2cb9d422e149b4017ae5e32eea580c3c2cc756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Wed, 5 Nov 2025 20:09:12 +0100 Subject: [PATCH 12/17] fix(ConvertTo-SingleSelect, ConvertFrom-SingleSelect, ConvertTo-Number): clear field value when empty --- private/projectDatabase/project_database_fields.ps1 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/private/projectDatabase/project_database_fields.ps1 b/private/projectDatabase/project_database_fields.ps1 index ba5c445..e1dc9b6 100644 --- a/private/projectDatabase/project_database_fields.ps1 +++ b/private/projectDatabase/project_database_fields.ps1 @@ -105,6 +105,7 @@ function ConvertFrom-SingleSelect{ ) process{ + # Clear the value of field if([string]::IsNullOrEmpty($Value)){ return $null } @@ -134,6 +135,12 @@ function ConvertTo-SingleSelect{ [Parameter(ValueFromPipeline)][string]$Value ) process{ + + # Clear the value of field + if([string]::IsNullOrEmpty($Value)){ + return $null + } + $ret = $Field.options.$Value return $ret } @@ -223,6 +230,12 @@ function ConvertTo-Number { [Parameter(ValueFromPipeline)][string]$Value ) process { + + # Clear the value of field + if([string]::IsNullOrWhiteSpace($Value)){ + return $null + } + $regex = [regex]"^[^\d-]*(-?(?:\d|(?<=\d)\.(?=\d{3}))+(?:,\d+)?|-?(?:\d|(?<=\d),(?=\d{3}))+(?:\.\d+)?)[^\d]*$" # Get the numeric part from the string From d46d4893aaa1274a1d317e0dbfcd3a13b2e0ad4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Wed, 5 Nov 2025 20:09:35 +0100 Subject: [PATCH 13/17] refactor(GetProjectItemByUrl): enhance functionality with PassThru parameter and update error handling --- public/items/project_item.ps1 | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/public/items/project_item.ps1 b/public/items/project_item.ps1 index 208811a..442920c 100644 --- a/public/items/project_item.ps1 +++ b/public/items/project_item.ps1 @@ -52,11 +52,13 @@ function Get-ProjectItem { function Get-ProjectItemByUrl{ [CmdletBinding()] + [Alias ("gpiu")] param( [Parameter(Mandatory, ValueFromPipeline, Position = 0)][string]$Url, [Parameter()][string]$Owner, [Parameter()][string]$ProjectNumber, - [Parameter()][switch]$Force + [Parameter()][switch]$Force, + [Parameter()][switch]$PassThru ) begin { @@ -74,19 +76,25 @@ function Get-ProjectItemByUrl{ $item = Get-ItemByUrl -Database $db -Url $Url - # TODO: Create a Resolve-ProjectItemByUrl so that we can udpate the Project - # if item is not cached but exists in projects. + # TODO: Create a Resolve-ProjectItemByUrl - Depend on function to get item from project remote by url + # Get-ItemByUrl only check cache so we need a function that will retreive item from project remote + # and update the project cache. # This function depends on the capacity to retreive items by filter # Project API has just been updated to allow search project items if(-not $item){ - "Item not found for URL [$Url]" | Write-MyError + # "Item not found for URL [$Url]" | Write-MyError return } - return $item + if($PassThru){ + $ret = $item + } else { + $ret = Format-ProjectItem -Item $item -Attributes @("id", "Title") + } + return $ret } -} Export-ModuleMember -Function Get-ProjectItemByUrl +} Export-ModuleMember -Function Get-ProjectItemByUrl -Alias "gpiu" function Test-ProjectItem { [CmdletBinding()] @@ -598,10 +606,10 @@ function Remove-ProjectItem { return $itemUrl } - "Deleting issue associated to item [$ItemId]" | Write-Verbose + "Deleting issue associated to item [$ItemId]" | Write-MyDebug if ($item.urlContent) { try { - $result = Remove-IssueDirect -Url $item.url + $result = Remove-IssueDirect -Url $item.urlContent } catch { "Issue associated to item [$ItemId] could not be deleted: $_" | Write-MyWarning return $false From 30a9f3c78cbb8a6099f1f46c711687a01b3dfc08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Wed, 5 Nov 2025 20:09:46 +0100 Subject: [PATCH 14/17] refactor(Set-Project): update parameter attributes for pipeline compatibility --- public/project/getproject.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/project/getproject.ps1 b/public/project/getproject.ps1 index adf4f53..c690524 100644 --- a/public/project/getproject.ps1 +++ b/public/project/getproject.ps1 @@ -84,8 +84,8 @@ function Open-Project{ function Set-Project { [CmdletBinding()] param( - [Parameter()][string]$Owner, - [Parameter(ValueFromPipeline,Position=1)][int]$ProjectNumber + [Parameter(ValueFromPipelineByPropertyName, Position = 0)][string]$Owner, + [Parameter(ValueFromPipelineByPropertyName, Position = 1)][string]$ProjectNumber ) process { From d648c9b68b039c8b1f87cae077381a06c82b4b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Wed, 5 Nov 2025 20:10:01 +0100 Subject: [PATCH 15/17] refactor(Show-ProjectItem): enhance addJumpLine calls with descriptive messages --- public/items/project_item_show.ps1 | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/public/items/project_item_show.ps1 b/public/items/project_item_show.ps1 index 2f3cfe1..27c578b 100644 --- a/public/items/project_item_show.ps1 +++ b/public/items/project_item_show.ps1 @@ -38,7 +38,7 @@ function Show-ProjectItem{ } # Before all - addJumpLine + addJumpLine -message "Header Start" # title bar # ($item.RepositoryOwner + "/") | write -Color Cyan @@ -47,27 +47,28 @@ function Show-ProjectItem{ addSpace $item.Title | write -Color Yellow -BetweenQuotes - addJumpLine + addJumpLine -message "Header End" # URL $item.url | write -Color White - addJumpLine + addJumpLine -message "End Url" # Fields by line if($FieldsToShow){ - addJumpLine + addJumpLine -message "Fields Before" foreach($line in $FieldsToShow){ ShowAttribLine -AttributesToShow $line -Item $item } } - addJumpLine + addJumpLine -message "Fields After" # Body "Body" | writeHeader $item.Body | write -Color Gray + addJumpLine -message "Body End" # Comments if($AllComments){ @@ -227,10 +228,12 @@ function writeComment2{ writeHeader $header -Author $Comment.author -UpdatedAt $Comment.updatedAt - addJumpLine -message "Header Done" + addJumpLine -message "Body Start" $Comment.body | write -Color Gray + addJumpLine -message "Body End" + } } @@ -345,16 +348,12 @@ function Write-ToBuffer { ) if($null -ne $script:outputBuffer){ - "Writing to buffer" | Write-MyDebug -section "WriteBuffer" - + $script:outputBuffer += $Message if(-not $NoNewLine){ $script:outputBuffer += "`n" } - - } else { - "No output buffer defined" | Write-MyDebug -section "WriteBuffer" } } \ No newline at end of file From 548c2923c1c487f9a0518c2e0fafdd5f0079b81c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Wed, 5 Nov 2025 20:17:42 +0100 Subject: [PATCH 16/17] fix(Get-ProjectIssue): update Get-ProjectItemByUrl call to include PassThru parameter --- public/issues/Get-ProjectIssue.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/issues/Get-ProjectIssue.ps1 b/public/issues/Get-ProjectIssue.ps1 index 8019e02..3d297a5 100644 --- a/public/issues/Get-ProjectIssue.ps1 +++ b/public/issues/Get-ProjectIssue.ps1 @@ -37,7 +37,7 @@ function Get-ProjectIssue { # Check the project cache of the default project $owner,$projectNumber = Get-OwnerAndProjectNumber - $item = Get-ProjectItemByUrl -Owner $owner -ProjectNumber $projectNumber -Url $Url -Force:$Force + $item = Get-ProjectItemByUrl -Owner $owner -ProjectNumber $projectNumber -Url $Url -PassThru -Force:$Force if( $item ) { $issue = $item | Convert-ItemToIssue return $issue From 9139e82edcab0a4ba785f223c55270fbdc67b1a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Wed, 5 Nov 2025 20:26:45 +0100 Subject: [PATCH 17/17] fix(Test_SearchProjectItem_AND_Filter): update title string formatting for consistency --- Test/public/project_item.searchprojectitem.test.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Test/public/project_item.searchprojectitem.test.ps1 b/Test/public/project_item.searchprojectitem.test.ps1 index 79bd576..0a68593 100644 --- a/Test/public/project_item.searchprojectitem.test.ps1 +++ b/Test/public/project_item.searchprojectitem.test.ps1 @@ -111,8 +111,8 @@ function Test_SearchProjectItem_AND_Filter_SUCCESS { MockCall_GetProject $p -Cache $i = $p.issue - $str = '"Title": "{title}",' -replace "{title}",$i.title - $newStr = '"Title": "{title} UniqueSearchAlpha UniqueSearchBeta",' -replace "{title}",$i.title + $str = '"{title}"' -replace '{title}',$i.title + $newStr = '"{title} UniqueSearchAlpha UniqueSearchBeta"' -replace '{title}',$i.title # Add content to the title of a file $dbpathh = Invoke-MyCommand -Command "Invoke-ProjectHelperGetDatabaseStorePath" | Join-Path -ChildPath octodemo_700.json