fixed ps scripts

This commit is contained in:
Reynold Lariza
2025-08-28 22:30:40 +08:00
parent 833eb9448a
commit f250f81753
6 changed files with 313 additions and 447 deletions

View File

@@ -36,26 +36,15 @@
#> #>
param( param(
[Parameter(ParameterSetName="File")]
[string]$fl, [string]$fl,
[Parameter(ParameterSetName="Code")]
[string]$code, [string]$code,
[Parameter(ParameterSetName="File")]
[Parameter(ParameterSetName="Code")]
[string]$to, [string]$to,
[Parameter(ParameterSetName="File")]
[Parameter(ParameterSetName="Code")]
[switch]$ve, [switch]$ve,
[Parameter(ParameterSetName="Help", Mandatory=$true)]
[switch]$hp [switch]$hp
) )
# Show help if requested # Show help if no parameters provided or help requested
if ($hp) { if ($hp -or (-not $fl -and -not $code)) {
Get-Help $MyInvocation.MyCommand.Path -Detailed Get-Help $MyInvocation.MyCommand.Path -Detailed
exit 0 exit 0
} }

View File

@@ -8,35 +8,35 @@
A user-friendly wrapper around 'sf data export' that simplifies data export A user-friendly wrapper around 'sf data export' that simplifies data export
from Salesforce orgs with SOQL query support, multiple formats, and intelligent defaults. from Salesforce orgs with SOQL query support, multiple formats, and intelligent defaults.
.PARAMETER Query .PARAMETER qy
SOQL query to export data (alias: -qy) SOQL query to export data
.PARAMETER File .PARAMETER fl
File containing SOQL query (alias: -fl) File containing SOQL query
.PARAMETER SObject .PARAMETER so
Standard object query (exports common fields) (alias: -so) Standard object query (exports common fields)
.PARAMETER Output .PARAMETER ot
Output file path (default: export.csv) (alias: -ot) Output file path (default: export.csv)
.PARAMETER TargetOrg .PARAMETER to
Target org username or alias (alias: -to) Target org username or alias
.PARAMETER Format .PARAMETER fm
Output format: csv, json (default: csv) (alias: -fm) Output format: csv, json (default: csv)
.PARAMETER Bulk .PARAMETER bk
Use bulk API for large datasets (alias: -bk) Use bulk API for large datasets
.PARAMETER Wait .PARAMETER wt
Wait time in minutes (default: 10) (alias: -wt) Wait time in minutes (default: 10)
.PARAMETER VerboseOutput .PARAMETER ve
Enable verbose output (alias: -ve) Enable verbose output
.PARAMETER Help .PARAMETER hp
Show this help message (alias: -hp) Show this help message
.EXAMPLE .EXAMPLE
.\sf-data-export.ps1 -qy "SELECT Id, Name FROM Account LIMIT 100" .\sf-data-export.ps1 -qy "SELECT Id, Name FROM Account LIMIT 100"
@@ -50,71 +50,21 @@
#> #>
param( param(
[Parameter(ParameterSetName="Query")] [string]$qy,
[Parameter(ParameterSetName="Help")] [string]$fl,
[Alias("qy")] [string]$so,
[string]$Query, [string]$ot = "export.csv",
[string]$to,
[Parameter(ParameterSetName="File")]
[Parameter(ParameterSetName="Help")]
[Alias("fl")]
[string]$File,
[Parameter(ParameterSetName="SObject")]
[Parameter(ParameterSetName="Help")]
[Alias("so")]
[string]$SObject,
[Parameter(ParameterSetName="Query")]
[Parameter(ParameterSetName="File")]
[Parameter(ParameterSetName="SObject")]
[Parameter(ParameterSetName="Help")]
[Alias("ot")]
[string]$Output = "export.csv",
[Parameter(ParameterSetName="Query")]
[Parameter(ParameterSetName="File")]
[Parameter(ParameterSetName="SObject")]
[Parameter(ParameterSetName="Help")]
[Alias("to")]
[string]$TargetOrg,
[Parameter(ParameterSetName="Query")]
[Parameter(ParameterSetName="File")]
[Parameter(ParameterSetName="SObject")]
[Parameter(ParameterSetName="Help")]
[ValidateSet("csv", "json")] [ValidateSet("csv", "json")]
[Alias("fm")] [string]$fm = "csv",
[string]$Format = "csv", [switch]$bk,
[int]$wt = 10,
[Parameter(ParameterSetName="Query")] [switch]$ve,
[Parameter(ParameterSetName="File")] [switch]$hp
[Parameter(ParameterSetName="SObject")]
[Parameter(ParameterSetName="Help")]
[Alias("bk")]
[switch]$Bulk,
[Parameter(ParameterSetName="Query")]
[Parameter(ParameterSetName="File")]
[Parameter(ParameterSetName="SObject")]
[Parameter(ParameterSetName="Help")]
[Alias("wt")]
[int]$Wait = 10,
[Parameter(ParameterSetName="Query")]
[Parameter(ParameterSetName="File")]
[Parameter(ParameterSetName="SObject")]
[Parameter(ParameterSetName="Help")]
[Alias("ve")]
[switch]$VerboseOutput,
[Parameter(ParameterSetName="Help", Mandatory=$true)]
[Alias("hp")]
[switch]$Help
) )
# Show help if requested # Show help if no parameters provided or help requested
if ($Help) { if ($hp -or (-not $qy -and -not $fl -and -not $so)) {
Get-Help $MyInvocation.MyCommand.Path -Detailed Get-Help $MyInvocation.MyCommand.Path -Detailed
exit 0 exit 0
} }
@@ -196,39 +146,39 @@ if (-not (Test-SalesforceCLI)) {
} }
# Validate that exactly one query method is specified # Validate that exactly one query method is specified
$queryMethods = @($Query, $File, $SObject | Where-Object { $_ }).Count $queryMethods = @($qy, $fl, $so | Where-Object { $_ }).Count
if ($queryMethods -eq 0) { if ($queryMethods -eq 0) {
Write-Host "Error: Must specify one of: -Query, -File, or -SObject" -ForegroundColor Red Write-Host "Error: Must specify one of: -qy, -fl, or -so" -ForegroundColor Red
Write-Host "" Write-Host ""
Write-Host "Usage examples:" -ForegroundColor Yellow Write-Host "Usage examples:" -ForegroundColor Yellow
Write-Host " .\sf-data-export.ps1 -Query `"SELECT Id, Name FROM Account`"" -ForegroundColor Gray Write-Host " .\sf-data-export.ps1 -qy `"SELECT Id, Name FROM Account`"" -ForegroundColor Gray
Write-Host " .\sf-data-export.ps1 -File queries/accounts.soql" -ForegroundColor Gray Write-Host " .\sf-data-export.ps1 -fl queries/accounts.soql" -ForegroundColor Gray
Write-Host " .\sf-data-export.ps1 -SObject Account" -ForegroundColor Gray Write-Host " .\sf-data-export.ps1 -so Account" -ForegroundColor Gray
Write-Host "" Write-Host ""
Write-Host "Use -Help for detailed usage information." -ForegroundColor Yellow Write-Host "Use -hp for detailed usage information." -ForegroundColor Yellow
exit 1 exit 1
} }
if ($queryMethods -gt 1) { if ($queryMethods -gt 1) {
Write-Host "Error: Can only specify one of: -Query, -File, or -SObject" -ForegroundColor Red Write-Host "Error: Can only specify one of: -qy, -fl, or -so" -ForegroundColor Red
exit 1 exit 1
} }
# Determine the final query # Determine the final query
$finalQuery = "" $finalQuery = ""
if ($Query) { if ($qy) {
$finalQuery = $Query $finalQuery = $qy
Write-Host "Using inline query" -ForegroundColor Green Write-Host "Using inline query" -ForegroundColor Green
} elseif ($File) { } elseif ($fl) {
if (-not (Test-Path $File)) { if (-not (Test-Path $fl)) {
Write-Host "Error: Query file not found: $File" -ForegroundColor Red Write-Host "Error: Query file not found: $fl" -ForegroundColor Red
exit 1 exit 1
} }
$finalQuery = Get-Content $File -Raw $finalQuery = Get-Content $fl -Raw
Write-Host "Using query from file: $File" -ForegroundColor Green Write-Host "Using query from file: $fl" -ForegroundColor Green
} elseif ($SObject) { } elseif ($so) {
$finalQuery = New-SObjectQuery $SObject $finalQuery = New-SObjectQuery $so
Write-Host "Using standard query for $SObject" -ForegroundColor Green Write-Host "Using standard query for $so" -ForegroundColor Green
} }
# Validate the query # Validate the query
@@ -237,30 +187,30 @@ if (-not (Test-SOQLQuery $finalQuery)) {
} }
# Build the sf command based on bulk vs regular query # Build the sf command based on bulk vs regular query
if ($Bulk) { if ($bk) {
# Use Bulk API 2.0 for large datasets # Use Bulk API 2.0 for large datasets
$sfArgs = @("data", "export", "bulk", "--query", $finalQuery, "--output-file", $Output, "--result-format", $Format) $sfArgs = @("data", "export", "bulk", "--query", $finalQuery, "--output-file", $ot, "--result-format", $fm)
if ($Wait -ne 10) { if ($wt -ne 10) {
$sfArgs += "--wait" $sfArgs += "--wait"
$sfArgs += $Wait.ToString() $sfArgs += $wt.ToString()
} }
Write-Host "Using Bulk API 2.0" -ForegroundColor Yellow Write-Host "Using Bulk API 2.0" -ForegroundColor Yellow
} else { } else {
# Use regular data query for smaller datasets # Use regular data query for smaller datasets
$sfArgs = @("data", "query", "--query", $finalQuery, "--output-file", $Output, "--result-format", $Format) $sfArgs = @("data", "query", "--query", $finalQuery, "--output-file", $ot, "--result-format", $fm)
} }
# Add optional parameters # Add optional parameters
if ($TargetOrg) { if ($to) {
$sfArgs += "--target-org" $sfArgs += "--target-org"
$sfArgs += $TargetOrg $sfArgs += $to
Write-Host "Target org: $TargetOrg" -ForegroundColor Cyan Write-Host "Target org: $to" -ForegroundColor Cyan
} }
Write-Host "Output format: $Format" -ForegroundColor Cyan Write-Host "Output format: $fm" -ForegroundColor Cyan
Write-Host "Output file: $Output" -ForegroundColor Cyan Write-Host "Output file: $ot" -ForegroundColor Cyan
# Note: sf data commands don't support --verbose flag # Note: sf data commands don't support --verbose flag
# VerboseOutput only affects the script's own output (query preview) # VerboseOutput only affects the script's own output (query preview)
@@ -271,7 +221,7 @@ Write-Host "📊 Starting Data Export" -ForegroundColor Blue
Write-Host "=======================" -ForegroundColor Blue Write-Host "=======================" -ForegroundColor Blue
# Show query preview if verbose # Show query preview if verbose
if ($VerboseOutput) { if ($ve) {
Write-Host "" Write-Host ""
Write-Host "📝 SOQL Query:" -ForegroundColor Yellow Write-Host "📝 SOQL Query:" -ForegroundColor Yellow
Write-Host "----------------------------------------" -ForegroundColor Gray Write-Host "----------------------------------------" -ForegroundColor Gray
@@ -294,8 +244,8 @@ try {
Write-Host "✅ Data export completed successfully!" -ForegroundColor Green Write-Host "✅ Data export completed successfully!" -ForegroundColor Green
# Show file information if it exists # Show file information if it exists
if (Test-Path $Output) { if (Test-Path $ot) {
$fileInfo = Get-Item $Output $fileInfo = Get-Item $ot
$fileSize = if ($fileInfo.Length -gt 1MB) { $fileSize = if ($fileInfo.Length -gt 1MB) {
"{0:N1} MB" -f ($fileInfo.Length / 1MB) "{0:N1} MB" -f ($fileInfo.Length / 1MB)
} elseif ($fileInfo.Length -gt 1KB) { } elseif ($fileInfo.Length -gt 1KB) {
@@ -304,16 +254,16 @@ try {
"$($fileInfo.Length) bytes" "$($fileInfo.Length) bytes"
} }
if ($Format -eq "csv") { if ($fm -eq "csv") {
# Count records (excluding header) # Count records (excluding header)
$recordCount = (Get-Content $Output).Count - 1 $recordCount = (Get-Content $ot).Count - 1
Write-Host "📁 Exported $recordCount records to $Output ($fileSize)" -ForegroundColor Cyan Write-Host "📁 Exported $recordCount records to $ot ($fileSize)" -ForegroundColor Cyan
} else { } else {
Write-Host "📁 Data exported to $Output ($fileSize)" -ForegroundColor Cyan Write-Host "📁 Data exported to $ot ($fileSize)" -ForegroundColor Cyan
} }
} }
if ($VerboseOutput) { if ($ve) {
Write-Host "💡 Use a spreadsheet application or text editor to view the exported data" -ForegroundColor Yellow Write-Host "💡 Use a spreadsheet application or text editor to view the exported data" -ForegroundColor Yellow
} }
} else { } else {

View File

@@ -8,38 +8,38 @@
A user-friendly wrapper around 'sf data import' that simplifies data import A user-friendly wrapper around 'sf data import' that simplifies data import
to Salesforce orgs with CSV/JSON support, upsert operations, and intelligent validation. to Salesforce orgs with CSV/JSON support, upsert operations, and intelligent validation.
.PARAMETER File .PARAMETER fl
CSV or JSON file to import (alias: -fl) CSV or JSON file to import
.PARAMETER SObject .PARAMETER so
Target sObject type (alias: -so) Target sObject type
.PARAMETER Operation .PARAMETER op
Operation: insert, update, upsert (default: insert) (alias: -op) Operation: insert, update, upsert (default: insert)
.PARAMETER ExternalId .PARAMETER ei
External ID field for upsert/update operations (alias: -ei) External ID field for upsert/update operations
.PARAMETER TargetOrg .PARAMETER to
Target org username or alias (alias: -to) Target org username or alias
.PARAMETER Bulk .PARAMETER bk
Use bulk API for large datasets (alias: -bk) Use bulk API for large datasets
.PARAMETER Wait .PARAMETER wt
Wait time in minutes (default: 10) (alias: -wt) Wait time in minutes (default: 10)
.PARAMETER BatchSize .PARAMETER bs
Batch size for bulk operations (default: 10000) (alias: -bs) Batch size for bulk operations (default: 10000)
.PARAMETER IgnoreErrors .PARAMETER ie
Continue on errors (don't fail entire job) (alias: -ie) Continue on errors (don't fail entire job)
.PARAMETER VerboseOutput .PARAMETER ve
Enable verbose output (alias: -ve) Enable verbose output
.PARAMETER Help .PARAMETER hp
Show this help message (alias: -hp) Show this help message
.EXAMPLE .EXAMPLE
.\sf-data-import.ps1 -fl accounts.csv -so Account .\sf-data-import.ps1 -fl accounts.csv -so Account
@@ -57,54 +57,22 @@
#> #>
param( param(
[Parameter(ParameterSetName="Import", Mandatory)] [string]$fl,
[Alias("fl")] [string]$so,
[string]$File,
[Parameter(ParameterSetName="Import", Mandatory)]
[Alias("so")]
[string]$SObject,
[Parameter(ParameterSetName="Import")]
[ValidateSet("insert", "update", "upsert")] [ValidateSet("insert", "update", "upsert")]
[Alias("op")] [string]$op = "insert",
[string]$Operation = "insert", [string]$ei,
[string]$to,
[Parameter(ParameterSetName="Import")] [switch]$bk,
[Alias("ei")] [int]$wt = 10,
[string]$ExternalId, [int]$bs = 10000,
[switch]$ie,
[Parameter(ParameterSetName="Import")] [switch]$ve,
[Alias("to")] [switch]$hp
[string]$TargetOrg,
[Parameter(ParameterSetName="Import")]
[Alias("bk")]
[switch]$Bulk,
[Parameter(ParameterSetName="Import")]
[Alias("wt")]
[int]$Wait = 10,
[Parameter(ParameterSetName="Import")]
[Alias("bs")]
[int]$BatchSize = 10000,
[Parameter(ParameterSetName="Import")]
[Alias("ie")]
[switch]$IgnoreErrors,
[Parameter(ParameterSetName="Import")]
[Alias("ve")]
[switch]$VerboseOutput,
[Parameter(ParameterSetName="Help", Mandatory=$true)]
[Alias("hp")]
[switch]$Help
) )
# Show help if requested # Show help if no parameters provided or help requested
if ($Help) { if ($hp -or (-not $fl -and -not $so)) {
Get-Help $MyInvocation.MyCommand.Path -Detailed Get-Help $MyInvocation.MyCommand.Path -Detailed
exit 0 exit 0
} }
@@ -248,93 +216,93 @@ if (-not (Test-SalesforceCLI)) {
} }
# Validate file exists # Validate file exists
if (-not (Test-Path $File)) { if (-not (Test-Path $fl)) {
Write-Host "Error: File not found: $File" -ForegroundColor Red Write-Host "Error: File not found: $fl" -ForegroundColor Red
exit 1 exit 1
} }
# Validate external ID for upsert/update operations # Validate external ID for upsert/update operations
if (($Operation -eq "upsert" -or $Operation -eq "update") -and -not $ExternalId) { if (($op -eq "upsert" -or $op -eq "update") -and -not $ei) {
Write-Host "Error: External ID field is required for $Operation operations" -ForegroundColor Red Write-Host "Error: External ID field is required for $op operations" -ForegroundColor Red
exit 1 exit 1
} }
# Detect and validate file format # Detect and validate file format
$fileFormat = Get-FileFormat $File $fileFormat = Get-FileFormat $fl
Write-Host "Using file: $File" -ForegroundColor Green Write-Host "Using file: $fl" -ForegroundColor Green
Write-Host "Detected format: $fileFormat" -ForegroundColor Cyan Write-Host "Detected format: $fileFormat" -ForegroundColor Cyan
# Validate file content # Validate file content
switch ($fileFormat) { switch ($fileFormat) {
"csv" { "csv" {
if (-not (Test-CSVFile $File)) { if (-not (Test-CSVFile $fl)) {
exit 1 exit 1
} }
} }
"json" { "json" {
if (-not (Test-JSONFile $File)) { if (-not (Test-JSONFile $fl)) {
exit 1 exit 1
} }
} }
} }
# Show file preview if verbose # Show file preview if verbose
if ($VerboseOutput) { if ($ve) {
Show-FilePreview $File $fileFormat Show-FilePreview $fl $fileFormat
} }
# Build the sf command based on file format # Build the sf command based on file format
if ($fileFormat -eq "csv") { if ($fileFormat -eq "csv") {
# Use bulk import for CSV files # Use bulk import for CSV files
$sfArgs = @("data", "import", "bulk", "--file", $File, "--sobject", $SObject) $sfArgs = @("data", "import", "bulk", "--file", $fl, "--sobject", $so)
} else { } else {
# Use tree import for JSON files # Use tree import for JSON files
$sfArgs = @("data", "import", "tree", "--files", $File) $sfArgs = @("data", "import", "tree", "--files", $fl)
} }
# Add optional parameters # Add optional parameters
if ($TargetOrg) { if ($to) {
$sfArgs += "--target-org" $sfArgs += "--target-org"
$sfArgs += $TargetOrg $sfArgs += $to
Write-Host "Target org: $TargetOrg" -ForegroundColor Cyan Write-Host "Target org: $to" -ForegroundColor Cyan
} }
if ($ExternalId) { if ($ei) {
$sfArgs += "--external-id" $sfArgs += "--external-id"
$sfArgs += $ExternalId $sfArgs += $ei
Write-Host "External ID field: $ExternalId" -ForegroundColor Cyan Write-Host "External ID field: $ei" -ForegroundColor Cyan
} }
if ($Bulk) { if ($bk) {
$sfArgs += "--bulk" $sfArgs += "--bulk"
Write-Host "Using Bulk API" -ForegroundColor Yellow Write-Host "Using Bulk API" -ForegroundColor Yellow
} }
if ($Wait -ne 10) { if ($wt -ne 10) {
$sfArgs += "--wait" $sfArgs += "--wait"
$sfArgs += $Wait.ToString() $sfArgs += $wt.ToString()
} }
if ($Bulk -and $BatchSize -ne 10000) { if ($bk -and $bs -ne 10000) {
$sfArgs += "--batch-size" $sfArgs += "--batch-size"
$sfArgs += $BatchSize.ToString() $sfArgs += $bs.ToString()
Write-Host "Batch size: $BatchSize" -ForegroundColor Cyan Write-Host "Batch size: $bs" -ForegroundColor Cyan
} }
if ($IgnoreErrors) { if ($ie) {
$sfArgs += "--ignore-errors" $sfArgs += "--ignore-errors"
Write-Host "Ignoring individual record errors" -ForegroundColor Yellow Write-Host "Ignoring individual record errors" -ForegroundColor Yellow
} }
# Note: sf data import commands don't support --verbose flag # Note: sf data import commands don't support --verbose flag
# VerboseOutput only affects the script's own output (file preview) # ve only affects the script's own output (file preview)
# Display import information # Display import information
Write-Host "" Write-Host ""
Write-Host "📥 Starting Data Import" -ForegroundColor Blue Write-Host "📥 Starting Data Import" -ForegroundColor Blue
Write-Host "=======================" -ForegroundColor Blue Write-Host "=======================" -ForegroundColor Blue
Write-Host "Operation: $Operation" -ForegroundColor Cyan Write-Host "Operation: $op" -ForegroundColor Cyan
Write-Host "sObject: $SObject" -ForegroundColor Cyan Write-Host "sObject: $so" -ForegroundColor Cyan
# Display the command being run # Display the command being run
Write-Host "" Write-Host ""
@@ -350,19 +318,19 @@ try {
if ($exitCode -eq 0) { if ($exitCode -eq 0) {
Write-Host "✅ Data import completed successfully!" -ForegroundColor Green Write-Host "✅ Data import completed successfully!" -ForegroundColor Green
switch ($Operation) { switch ($op) {
"insert" { "insert" {
Write-Host "📊 Records inserted into $SObject" -ForegroundColor Cyan Write-Host "📊 Records inserted into $so" -ForegroundColor Cyan
} }
"update" { "update" {
Write-Host "📊 Records updated in $SObject" -ForegroundColor Cyan Write-Host "📊 Records updated in $so" -ForegroundColor Cyan
} }
"upsert" { "upsert" {
Write-Host "📊 Records upserted in $SObject (using $ExternalId as external ID)" -ForegroundColor Cyan Write-Host "📊 Records upserted in $so (using $ei as external ID)" -ForegroundColor Cyan
} }
} }
if ($VerboseOutput) { if ($ve) {
Write-Host "💡 Check the output above for detailed results and any warnings" -ForegroundColor Yellow Write-Host "💡 Check the output above for detailed results and any warnings" -ForegroundColor Yellow
} }
} else { } else {

View File

@@ -8,38 +8,38 @@
A user-friendly wrapper around 'sf apex tail log' that provides real-time A user-friendly wrapper around 'sf apex tail log' that provides real-time
debug log monitoring with filtering, formatting, and intelligent output colorization. debug log monitoring with filtering, formatting, and intelligent output colorization.
.PARAMETER o .PARAMETER to
Target org username or alias Target org username or alias
.PARAMETER UserId .PARAMETER ui
Specific user ID to monitor (default: current user) Specific user ID to monitor (default: current user)
.PARAMETER Level .PARAMETER lv
Log level: ERROR, WARN, INFO, DEBUG, FINE, FINER, FINEST Log level: ERROR, WARN, INFO, DEBUG, FINE, FINER, FINEST
.PARAMETER Duration .PARAMETER dr
How long to tail logs in minutes (default: 30) How long to tail logs in minutes (default: 30)
.PARAMETER Filter .PARAMETER ft
Filter log entries containing pattern Filter log entries containing pattern
.PARAMETER ApexOnly .PARAMETER ax
Show only Apex-related log entries Show only Apex-related log entries
.PARAMETER NoColors .PARAMETER nc
Disable colored output Disable colored output
.PARAMETER Verbose .PARAMETER ve
Enable verbose output with timestamps Enable verbose output with timestamps
.PARAMETER Help .PARAMETER hp
Show this help message Show this help message
.EXAMPLE .EXAMPLE
.\sf-logs-tail.ps1 .\sf-logs-tail.ps1
.\sf-logs-tail.ps1 -Level DEBUG -Duration 60 .\sf-logs-tail.ps1 -lv DEBUG -dr 60
.\sf-logs-tail.ps1 -Filter "MyClass" -ApexOnly .\sf-logs-tail.ps1 -ft "MyClass" -ax
.\sf-logs-tail.ps1 -o sandbox -UserId USER123 .\sf-logs-tail.ps1 -to sandbox -ui USER123
.NOTES .NOTES
This script automatically checks for Salesforce CLI installation and runs This script automatically checks for Salesforce CLI installation and runs
@@ -49,20 +49,26 @@
#> #>
param( param(
[string]$o, [string]$to,
[string]$UserId, [string]$ui,
[ValidateSet("ERROR", "WARN", "INFO", "DEBUG", "FINE", "FINER", "FINEST")] [ValidateSet("ERROR", "WARN", "INFO", "DEBUG", "FINE", "FINER", "FINEST")]
[string]$Level, [string]$lv,
[int]$Duration = 30, [int]$dr = 30,
[string]$Filter, [string]$ft,
[switch]$ApexOnly, [switch]$ax,
[switch]$NoColors, [switch]$nc,
[switch]$Verbose, [switch]$ve,
[switch]$Help [switch]$hp
) )
# Show help if no parameters provided
if (-not ($to -or $ui -or $lv -or $dr -ne 30 -or $ft -or $ax -or $nc -or $ve -or $hp)) {
Get-Help $MyInvocation.MyCommand.Path -Detailed
exit 0
}
# Show help if requested # Show help if requested
if ($Help) { if ($hp) {
Get-Help $MyInvocation.MyCommand.Path -Detailed Get-Help $MyInvocation.MyCommand.Path -Detailed
exit 0 exit 0
} }
@@ -181,7 +187,7 @@ if (-not (Test-SalesforceCLI)) {
} }
# Validate duration # Validate duration
if ($Duration -lt 1) { if ($dr -lt 1) {
Write-Host "Error: Duration must be at least 1 minute" -ForegroundColor Red Write-Host "Error: Duration must be at least 1 minute" -ForegroundColor Red
exit 1 exit 1
} }
@@ -190,19 +196,19 @@ if ($Duration -lt 1) {
$sfArgs = @("apex", "tail", "log") $sfArgs = @("apex", "tail", "log")
# Add optional parameters # Add optional parameters
if ($o) { if ($to) {
$sfArgs += "--target-org" $sfArgs += "--target-org"
$sfArgs += $o $sfArgs += $to
} }
if ($UserId) { if ($ui) {
$sfArgs += "--user-id" $sfArgs += "--user-id"
$sfArgs += $UserId $sfArgs += $ui
} }
if ($Level) { if ($lv) {
$sfArgs += "--debug-level" $sfArgs += "--debug-level"
$sfArgs += $Level $sfArgs += $lv
} }
# Set up signal handlers # Set up signal handlers
@@ -212,39 +218,39 @@ Set-SignalHandlers
Write-Host "📡 Starting Debug Log Tail" -ForegroundColor Blue Write-Host "📡 Starting Debug Log Tail" -ForegroundColor Blue
Write-Host "===========================" -ForegroundColor Blue Write-Host "===========================" -ForegroundColor Blue
if ($o) { if ($to) {
Write-Host "Target org: $o" -ForegroundColor Cyan Write-Host "Target org: $to" -ForegroundColor Cyan
} }
if ($UserId) { if ($ui) {
Write-Host "User ID: $UserId" -ForegroundColor Cyan Write-Host "User ID: $ui" -ForegroundColor Cyan
} else { } else {
Write-Host "User: Current user" -ForegroundColor Cyan Write-Host "User: Current user" -ForegroundColor Cyan
} }
if ($Level) { if ($lv) {
Write-Host "Log level: " -ForegroundColor Cyan -NoNewline Write-Host "Log level: " -ForegroundColor Cyan -NoNewline
Write-ColorizedLogLevel $Level Write-ColorizedLogLevel $lv
Write-Host "" Write-Host ""
} }
Write-Host "Duration: $Duration minutes" -ForegroundColor Cyan Write-Host "Duration: $dr minutes" -ForegroundColor Cyan
if ($Filter) { if ($ft) {
Write-Host "Filter: $Filter" -ForegroundColor Cyan Write-Host "Filter: $ft" -ForegroundColor Cyan
} }
if ($ApexOnly) { if ($ax) {
Write-Host "Mode: Apex-only logs" -ForegroundColor Yellow Write-Host "Mode: Apex-only logs" -ForegroundColor Yellow
} }
if ($Verbose) { if ($ve) {
Write-Host "Verbose: Enabled (with timestamps)" -ForegroundColor Yellow Write-Host "Verbose: Enabled (with timestamps)" -ForegroundColor Yellow
} }
# Color settings # Color settings
$showColors = -not $NoColors $showColors = -not $nc
if ($NoColors) { if ($nc) {
Write-Host "Colors: Disabled" -ForegroundColor Gray Write-Host "Colors: Disabled" -ForegroundColor Gray
} }
@@ -253,7 +259,7 @@ Write-Host "Press Ctrl+C to stop tailing logs" -ForegroundColor Yellow
Write-Host "" Write-Host ""
# Display the command being run # Display the command being run
if ($Verbose) { if ($ve) {
Write-Host "Executing: sf $($sfArgs -join ' ')" -ForegroundColor Gray Write-Host "Executing: sf $($sfArgs -join ' ')" -ForegroundColor Gray
Write-Host "" Write-Host ""
} }
@@ -265,14 +271,14 @@ try {
& sf @sfArgs 2>$null & sf @sfArgs 2>$null
} -ArgumentList $sfArgs } -ArgumentList $sfArgs
$timeoutTime = (Get-Date).AddMinutes($Duration) $timeoutTime = (Get-Date).AddMinutes($dr)
while ((Get-Date) -lt $timeoutTime -and $job.State -eq "Running") { while ((Get-Date) -lt $timeoutTime -and $job.State -eq "Running") {
$output = Receive-Job $job $output = Receive-Job $job
foreach ($line in $output) { foreach ($line in $output) {
if (Test-ShowLogEntry $line $Filter $ApexOnly) { if (Test-ShowLogEntry $line $ft $ax) {
Write-FormattedLogEntry $line $showColors $Verbose Write-FormattedLogEntry $line $showColors $ve
} }
} }
@@ -282,8 +288,8 @@ try {
# Get any remaining output # Get any remaining output
$finalOutput = Receive-Job $job $finalOutput = Receive-Job $job
foreach ($line in $finalOutput) { foreach ($line in $finalOutput) {
if (Test-ShowLogEntry $line $Filter $ApexOnly) { if (Test-ShowLogEntry $line $ft $ax) {
Write-FormattedLogEntry $line $showColors $Verbose Write-FormattedLogEntry $line $showColors $ve
} }
} }
@@ -299,7 +305,7 @@ try {
Write-Host "" Write-Host ""
if ($exitCode -eq 124) { if ($exitCode -eq 124) {
Write-Host "⏰ Log tail timed out after $Duration minutes" -ForegroundColor Yellow Write-Host "⏰ Log tail timed out after $dr minutes" -ForegroundColor Yellow
} elseif ($exitCode -eq 0) { } elseif ($exitCode -eq 0) {
Write-Host "✅ Log tail completed successfully" -ForegroundColor Green Write-Host "✅ Log tail completed successfully" -ForegroundColor Green
} else { } else {

View File

@@ -8,35 +8,35 @@
A user-friendly wrapper around 'sf project retrieve' commands that simplifies A user-friendly wrapper around 'sf project retrieve' commands that simplifies
metadata retrieval from Salesforce orgs with intelligent defaults and validation. metadata retrieval from Salesforce orgs with intelligent defaults and validation.
.PARAMETER MetadataTypes .PARAMETER mt
Comma-separated list of metadata types to retrieve (e.g., "ApexClass,CustomObject") Comma-separated list of metadata types to retrieve (e.g., "ApexClass,CustomObject")
.PARAMETER Manifest .PARAMETER mf
Path to package.xml or manifest file for retrieval Path to package.xml or manifest file for retrieval
.PARAMETER Package .PARAMETER pk
Package name for package-based retrieval Package name for package-based retrieval
.PARAMETER OutputDir .PARAMETER od
Output directory for retrieved metadata (default: current directory) Output directory for retrieved metadata (default: current directory)
.PARAMETER o .PARAMETER to
Target org username or alias (uses default if not specified) Target org username or alias (uses default if not specified)
.PARAMETER Wait .PARAMETER wt
Wait time in minutes for the retrieve operation (default: 10) Wait time in minutes for the retrieve operation (default: 10)
.PARAMETER VerboseOutput .PARAMETER ve
Enable verbose output Enable verbose output
.PARAMETER Help .PARAMETER hp
Show this help message Show this help message
.EXAMPLE .EXAMPLE
.\sf-retrieve.ps1 -MetadataTypes "ApexClass,CustomObject" -o myorg -OutputDir retrieved .\sf-retrieve.ps1 -mt "ApexClass,CustomObject" -to myorg -od retrieved
.\sf-retrieve.ps1 -Manifest "manifest/package.xml" .\sf-retrieve.ps1 -mf "manifest/package.xml"
.\sf-retrieve.ps1 -Package "MyPackage" -o "myorg" .\sf-retrieve.ps1 -pk "MyPackage" -to "myorg"
.\sf-retrieve.ps1 -MetadataTypes "Flow" -OutputDir "./retrieved" -Verbose .\sf-retrieve.ps1 -mt "Flow" -od "./retrieved" -ve
.NOTES .NOTES
This script automatically checks for Salesforce CLI installation and runs This script automatically checks for Salesforce CLI installation and runs
@@ -44,42 +44,24 @@
#> #>
param( param(
[Parameter(ParameterSetName="Types")] [string]$mt,
[string]$MetadataTypes, [string]$mf,
[string]$pk,
[Parameter(ParameterSetName="Manifest")] [string]$od,
[string]$Manifest, [string]$to,
[int]$wt = 10,
[Parameter(ParameterSetName="Package")] [switch]$ve,
[string]$Package, [switch]$hp
[Parameter(ParameterSetName="Types")]
[Parameter(ParameterSetName="Manifest")]
[Parameter(ParameterSetName="Package")]
[string]$OutputDir,
[Parameter(ParameterSetName="Types")]
[Parameter(ParameterSetName="Manifest")]
[Parameter(ParameterSetName="Package")]
[string]$o,
[Parameter(ParameterSetName="Types")]
[Parameter(ParameterSetName="Manifest")]
[Parameter(ParameterSetName="Package")]
[int]$Wait = 10,
[Parameter(ParameterSetName="Types")]
[Parameter(ParameterSetName="Manifest")]
[Parameter(ParameterSetName="Package")]
[switch]$VerboseOutput,
[Parameter(ParameterSetName="Help", Mandatory=$true)]
[Alias("hp")]
[switch]$Help
) )
# Show help if no parameters provided
if (-not ($mt -or $mf -or $pk -or $hp)) {
Get-Help $MyInvocation.MyCommand.Path -Detailed
exit 0
}
# Show help if requested # Show help if requested
if ($Help) { if ($hp) {
Get-Help $MyInvocation.MyCommand.Path -Detailed Get-Help $MyInvocation.MyCommand.Path -Detailed
exit 0 exit 0
} }
@@ -120,27 +102,27 @@ if (-not (Test-SalesforceCLI)) {
} }
# Validate that exactly one retrieval method is specified # Validate that exactly one retrieval method is specified
$methodCount = @($MetadataTypes, $Manifest, $Package | Where-Object { $_ }).Count $methodCount = @($mt, $mf, $pk | Where-Object { $_ }).Count
if ($methodCount -eq 0) { if ($methodCount -eq 0) {
Write-Host "Error: Must specify one of: -MetadataTypes, -Manifest, or -Package" -ForegroundColor Red Write-Host "Error: Must specify one of: -mt, -mf, or -pk" -ForegroundColor Red
Write-Host "" Write-Host ""
Write-Host "Usage examples:" -ForegroundColor Yellow Write-Host "Usage examples:" -ForegroundColor Yellow
Write-Host " .\sf-retrieve.ps1 -MetadataTypes `"ApexClass,CustomObject`"" -ForegroundColor Gray Write-Host " .\sf-retrieve.ps1 -mt `"ApexClass,CustomObject`"" -ForegroundColor Gray
Write-Host " .\sf-retrieve.ps1 -Manifest `"manifest/package.xml`"" -ForegroundColor Gray Write-Host " .\sf-retrieve.ps1 -mf `"manifest/package.xml`"" -ForegroundColor Gray
Write-Host " .\sf-retrieve.ps1 -Package `"MyPackage`"" -ForegroundColor Gray Write-Host " .\sf-retrieve.ps1 -pk `"MyPackage`"" -ForegroundColor Gray
Write-Host "" Write-Host ""
Write-Host "Use -Help for detailed usage information." -ForegroundColor Yellow Write-Host "Use -hp for detailed usage information." -ForegroundColor Yellow
exit 1 exit 1
} }
if ($methodCount -gt 1) { if ($methodCount -gt 1) {
Write-Host "Error: Can only specify one of: -MetadataTypes, -Manifest, or -Package" -ForegroundColor Red Write-Host "Error: Can only specify one of: -mt, -mf, or -pk" -ForegroundColor Red
exit 1 exit 1
} }
# Validate manifest file exists if specified # Validate manifest file exists if specified
if ($Manifest -and -not (Test-Path $Manifest)) { if ($mf -and -not (Test-Path $mf)) {
Write-Host "Error: Manifest file not found: $Manifest" -ForegroundColor Red Write-Host "Error: Manifest file not found: $mf" -ForegroundColor Red
exit 1 exit 1
} }
@@ -148,43 +130,43 @@ if ($Manifest -and -not (Test-Path $Manifest)) {
$sfArgs = @("project", "retrieve", "start") $sfArgs = @("project", "retrieve", "start")
# Add retrieval method # Add retrieval method
if ($MetadataTypes) { if ($mt) {
$sfArgs += "--metadata" $sfArgs += "--metadata"
$sfArgs += $MetadataTypes $sfArgs += $mt
Write-Host "Retrieving metadata types: $MetadataTypes" -ForegroundColor Green Write-Host "Retrieving metadata types: $mt" -ForegroundColor Green
} elseif ($Manifest) { } elseif ($mf) {
$sfArgs += "--manifest" $sfArgs += "--manifest"
$sfArgs += $Manifest $sfArgs += $mf
Write-Host "Retrieving from manifest: $Manifest" -ForegroundColor Green Write-Host "Retrieving from manifest: $mf" -ForegroundColor Green
} elseif ($Package) { } elseif ($pk) {
$sfArgs += "--package-name" $sfArgs += "--package-name"
$sfArgs += $Package $sfArgs += $pk
Write-Host "Retrieving package: $Package" -ForegroundColor Green Write-Host "Retrieving package: $pk" -ForegroundColor Green
} }
# Add optional parameters # Add optional parameters
if ($OutputDir) { if ($od) {
if (-not (Test-Path $OutputDir)) { if (-not (Test-Path $od)) {
Write-Host "Creating output directory: $OutputDir" -ForegroundColor Yellow Write-Host "Creating output directory: $od" -ForegroundColor Yellow
New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null New-Item -ItemType Directory -Path $od -Force | Out-Null
} }
$sfArgs += "--output-dir" $sfArgs += "--output-dir"
$sfArgs += $OutputDir $sfArgs += $od
} }
if ($o) { if ($to) {
$sfArgs += "--target-org" $sfArgs += "--target-org"
$sfArgs += $o $sfArgs += $to
Write-Host "Target org: $o" -ForegroundColor Cyan Write-Host "Target org: $to" -ForegroundColor Cyan
} }
if ($Wait -ne 10) { if ($wt -ne 10) {
$sfArgs += "--wait" $sfArgs += "--wait"
$sfArgs += $Wait.ToString() $sfArgs += $wt.ToString()
} }
# Add verbose flag if requested # Add verbose flag if requested
if ($VerboseOutput) { if ($ve) {
$sfArgs += "--verbose" $sfArgs += "--verbose"
} }

View File

@@ -8,41 +8,41 @@
A user-friendly wrapper around 'sf apex run test' that simplifies test execution A user-friendly wrapper around 'sf apex run test' that simplifies test execution
with better formatting, intelligent defaults, and comprehensive reporting options. with better formatting, intelligent defaults, and comprehensive reporting options.
.PARAMETER TestClasses .PARAMETER tc
Comma-separated list of test class names to run Comma-separated list of test class names to run
.PARAMETER TestMethods .PARAMETER tm
Comma-separated list of specific test methods to run (format: ClassName.methodName) Comma-separated list of specific test methods to run (format: ClassName.methodName)
.PARAMETER TestLevel .PARAMETER tl
Test level to run (RunLocalTests, RunAllTestsInOrg, RunSpecifiedTests) Test level to run (RunLocalTests, RunAllTestsInOrg, RunSpecifiedTests)
.PARAMETER Suite .PARAMETER st
Test suite name to run Test suite name to run
.PARAMETER Coverage .PARAMETER cv
Generate code coverage report Generate code coverage report
.PARAMETER Wait .PARAMETER wt
Wait time in minutes for test execution (default: 10) Wait time in minutes for test execution (default: 10)
.PARAMETER o .PARAMETER to
Target org username or alias (uses default if not specified) Target org username or alias (uses default if not specified)
.PARAMETER OutputDir .PARAMETER od
Directory to store test results and reports Directory to store test results and reports
.PARAMETER VerboseOutput .PARAMETER ve
Enable verbose test output Enable verbose test output
.PARAMETER Help .PARAMETER hp
Show this help message Show this help message
.EXAMPLE .EXAMPLE
.\sf-test-run.ps1 -TestClasses "AccountTest,ContactTest" .\sf-test-run.ps1 -tc "AccountTest,ContactTest"
.\sf-test-run.ps1 -TestLevel "RunLocalTests" -Coverage .\sf-test-run.ps1 -tl "RunLocalTests" -cv
.\sf-test-run.ps1 -TestMethods "AccountTest.testCreate,ContactTest.testUpdate" .\sf-test-run.ps1 -tm "AccountTest.testCreate,ContactTest.testUpdate"
.\sf-test-run.ps1 -Suite "AllTests" -Wait 15 -o "staging" .\sf-test-run.ps1 -st "AllTests" -wt 15 -to "staging"
.NOTES .NOTES
This script automatically checks for Salesforce CLI installation and runs This script automatically checks for Salesforce CLI installation and runs
@@ -50,56 +50,27 @@
#> #>
param( param(
[Parameter(ParameterSetName="Classes")] [string]$tc,
[string]$TestClasses, [string]$tm,
[Parameter(ParameterSetName="Methods")]
[string]$TestMethods,
[Parameter(ParameterSetName="Level")]
[ValidateSet("RunLocalTests", "RunAllTestsInOrg", "RunSpecifiedTests")] [ValidateSet("RunLocalTests", "RunAllTestsInOrg", "RunSpecifiedTests")]
[string]$TestLevel, [string]$tl,
[string]$st,
[Parameter(ParameterSetName="Suite")] [switch]$cv,
[string]$Suite, [int]$wt = 10,
[string]$to,
[Parameter(ParameterSetName="Classes")] [string]$od,
[Parameter(ParameterSetName="Methods")] [switch]$ve,
[Parameter(ParameterSetName="Level")] [switch]$hp
[Parameter(ParameterSetName="Suite")]
[switch]$Coverage,
[Parameter(ParameterSetName="Classes")]
[Parameter(ParameterSetName="Methods")]
[Parameter(ParameterSetName="Level")]
[Parameter(ParameterSetName="Suite")]
[int]$Wait = 10,
[Parameter(ParameterSetName="Classes")]
[Parameter(ParameterSetName="Methods")]
[Parameter(ParameterSetName="Level")]
[Parameter(ParameterSetName="Suite")]
[string]$o,
[Parameter(ParameterSetName="Classes")]
[Parameter(ParameterSetName="Methods")]
[Parameter(ParameterSetName="Level")]
[Parameter(ParameterSetName="Suite")]
[string]$OutputDir,
[Parameter(ParameterSetName="Classes")]
[Parameter(ParameterSetName="Methods")]
[Parameter(ParameterSetName="Level")]
[Parameter(ParameterSetName="Suite")]
[switch]$VerboseOutput,
[Parameter(ParameterSetName="Help", Mandatory=$true)]
[Alias("hp")]
[switch]$Help
) )
# Show help if no parameters provided
if (-not ($tc -or $tm -or $tl -or $st -or $hp)) {
Get-Help $MyInvocation.MyCommand.Path -Detailed
exit 0
}
# Show help if requested # Show help if requested
if ($Help) { if ($hp) {
Get-Help $MyInvocation.MyCommand.Path -Detailed Get-Help $MyInvocation.MyCommand.Path -Detailed
exit 0 exit 0
} }
@@ -140,17 +111,17 @@ if (-not (Test-SalesforceCLI)) {
} }
# Validate that at least one test specification is provided # Validate that at least one test specification is provided
$testSpecCount = @($TestClasses, $TestMethods, $TestLevel, $Suite | Where-Object { $_ }).Count $testSpecCount = @($tc, $tm, $tl, $st | Where-Object { $_ }).Count
if ($testSpecCount -eq 0) { if ($testSpecCount -eq 0) {
Write-Host "Error: Must specify one of: -TestClasses, -TestMethods, -TestLevel, or -Suite" -ForegroundColor Red Write-Host "Error: Must specify one of: -tc, -tm, -tl, or -st" -ForegroundColor Red
Write-Host "" Write-Host ""
Write-Host "Usage examples:" -ForegroundColor Yellow Write-Host "Usage examples:" -ForegroundColor Yellow
Write-Host " .\sf-test-run.ps1 -TestClasses `"AccountTest,ContactTest`"" -ForegroundColor Gray Write-Host " .\sf-test-run.ps1 -tc `"AccountTest,ContactTest`"" -ForegroundColor Gray
Write-Host " .\sf-test-run.ps1 -TestLevel `"RunLocalTests`" -Coverage" -ForegroundColor Gray Write-Host " .\sf-test-run.ps1 -tl `"RunLocalTests`" -cv" -ForegroundColor Gray
Write-Host " .\sf-test-run.ps1 -TestMethods `"AccountTest.testCreate`"" -ForegroundColor Gray Write-Host " .\sf-test-run.ps1 -tm `"AccountTest.testCreate`"" -ForegroundColor Gray
Write-Host " .\sf-test-run.ps1 -Suite `"AllTests`"" -ForegroundColor Gray Write-Host " .\sf-test-run.ps1 -st `"AllTests`"" -ForegroundColor Gray
Write-Host "" Write-Host ""
Write-Host "Use -Help for detailed usage information." -ForegroundColor Yellow Write-Host "Use -hp for detailed usage information." -ForegroundColor Yellow
exit 1 exit 1
} }
@@ -158,48 +129,48 @@ if ($testSpecCount -eq 0) {
$sfArgs = @("apex", "run", "test") $sfArgs = @("apex", "run", "test")
# Add test specification # Add test specification
if ($TestClasses) { if ($tc) {
$sfArgs += "--class-names" $sfArgs += "--class-names"
$sfArgs += $TestClasses $sfArgs += $tc
Write-Host "Running test classes: $TestClasses" -ForegroundColor Green Write-Host "Running test classes: $tc" -ForegroundColor Green
} elseif ($TestMethods) { } elseif ($tm) {
$sfArgs += "--tests" $sfArgs += "--tests"
$sfArgs += $TestMethods $sfArgs += $tm
Write-Host "Running test methods: $TestMethods" -ForegroundColor Green Write-Host "Running test methods: $tm" -ForegroundColor Green
} elseif ($TestLevel) { } elseif ($tl) {
$sfArgs += "--test-level" $sfArgs += "--test-level"
$sfArgs += $TestLevel $sfArgs += $tl
Write-Host "Running tests at level: $TestLevel" -ForegroundColor Green Write-Host "Running tests at level: $tl" -ForegroundColor Green
} elseif ($Suite) { } elseif ($st) {
$sfArgs += "--suite-names" $sfArgs += "--suite-names"
$sfArgs += $Suite $sfArgs += $st
Write-Host "Running test suite: $Suite" -ForegroundColor Green Write-Host "Running test suite: $st" -ForegroundColor Green
} }
# Add optional parameters # Add optional parameters
if ($o) { if ($to) {
$sfArgs += "--target-org" $sfArgs += "--target-org"
$sfArgs += $o $sfArgs += $to
Write-Host "Target org: $o" -ForegroundColor Cyan Write-Host "Target org: $to" -ForegroundColor Cyan
} }
if ($Wait -ne 10) { if ($wt -ne 10) {
$sfArgs += "--wait" $sfArgs += "--wait"
$sfArgs += $Wait.ToString() $sfArgs += $wt.ToString()
} }
if ($Coverage) { if ($cv) {
$sfArgs += "--code-coverage" $sfArgs += "--code-coverage"
Write-Host "Code coverage: Enabled" -ForegroundColor Yellow Write-Host "Code coverage: Enabled" -ForegroundColor Yellow
} }
if ($OutputDir) { if ($od) {
if (-not (Test-Path $OutputDir)) { if (-not (Test-Path $od)) {
Write-Host "Creating output directory: $OutputDir" -ForegroundColor Yellow Write-Host "Creating output directory: $od" -ForegroundColor Yellow
New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null New-Item -ItemType Directory -Path $od -Force | Out-Null
} }
$sfArgs += "--output-dir" $sfArgs += "--output-dir"
$sfArgs += $OutputDir $sfArgs += $od
} }
# Always use detailed output for better reporting # Always use detailed output for better reporting
@@ -208,7 +179,7 @@ $sfArgs += "--result-format"
$sfArgs += "human" $sfArgs += "human"
# Add verbose flag if requested # Add verbose flag if requested
if ($VerboseOutput) { if ($ve) {
$sfArgs += "--verbose" $sfArgs += "--verbose"
} }
@@ -237,12 +208,12 @@ try {
Write-Host "" Write-Host ""
Write-Host "✅ Tests completed successfully!" -ForegroundColor Green Write-Host "✅ Tests completed successfully!" -ForegroundColor Green
if ($Coverage) { if ($cv) {
Write-Host "📊 Code coverage report generated" -ForegroundColor Yellow Write-Host "📊 Code coverage report generated" -ForegroundColor Yellow
} }
if ($OutputDir) { if ($od) {
Write-Host "📁 Results saved to: $OutputDir" -ForegroundColor Cyan Write-Host "📁 Results saved to: $od" -ForegroundColor Cyan
} }
} else { } else {
Write-Host "" Write-Host ""