Files
sf-cli-wrapper/sf-apex-run.ps1
Reynold Lariza f250f81753 fixed ps scripts
2025-08-28 22:30:40 +08:00

239 lines
6.9 KiB
PowerShell

#!/usr/bin/env pwsh
<#
.SYNOPSIS
Anonymous Apex execution wrapper for Salesforce CLI
.DESCRIPTION
A user-friendly wrapper around 'sf apex run' that simplifies executing
anonymous Apex code from files or inline strings with better formatting
and error handling.
.PARAMETER fl
Path to Apex file to execute
.PARAMETER code
Inline Apex code to execute (alternative to -fl)
.PARAMETER to
Target org username or alias (uses default if not specified)
.PARAMETER ve
Enable verbose output showing execution details
.PARAMETER hp
Show this help message
.EXAMPLE
.\sf-apex-run.ps1 -fl "scripts/setup.apex"
.\sf-apex-run.ps1 -code "System.debug('Hello World');"
.\sf-apex-run.ps1 -fl "test.apex" -to "sandbox"
.\sf-apex-run.ps1 -code "Database.insert(new Account(Name='Test'));" -ve
.NOTES
This script automatically checks for Salesforce CLI installation and runs
diagnostics if the CLI is not found.
#>
param(
[string]$fl,
[string]$code,
[string]$to,
[switch]$ve,
[switch]$hp
)
# Show help if no parameters provided or help requested
if ($hp -or (-not $fl -and -not $code)) {
Get-Help $MyInvocation.MyCommand.Path -Detailed
exit 0
}
# Function to check if Salesforce CLI is installed
function Test-SalesforceCLI {
try {
$null = Get-Command sf -ErrorAction Stop
return $true
} catch {
return $false
}
}
# Function to run sf-check diagnostics
function Invoke-SalesforceCheck {
$checkScript = if (Test-Path "sf-check.ps1") {
".\sf-check.ps1"
} elseif (Test-Path "sf-check.sh") {
"bash sf-check.sh"
} else {
$null
}
if ($checkScript) {
Write-Host "Running Salesforce CLI diagnostics..." -ForegroundColor Yellow
Invoke-Expression $checkScript
} else {
Write-Host "Salesforce CLI not found and no diagnostic script available." -ForegroundColor Red
Write-Host "Please install the Salesforce CLI: https://developer.salesforce.com/tools/salesforcecli" -ForegroundColor Red
}
}
# Function to display code preview
function Show-CodePreview {
param([string]$CodeContent, [string]$Source)
Write-Host "📝 Apex Code ($Source):" -ForegroundColor Yellow
Write-Host "----------------------------------------" -ForegroundColor Gray
# Show first few lines of code for preview
$lines = $CodeContent -split "`n"
$previewLines = if ($lines.Count -gt 10) {
$lines[0..9] + @("... (truncated, $($lines.Count - 10) more lines)")
} else {
$lines
}
foreach ($line in $previewLines) {
Write-Host " $line" -ForegroundColor White
}
Write-Host "----------------------------------------" -ForegroundColor Gray
}
# Silently check for Salesforce CLI
if (-not (Test-SalesforceCLI)) {
Invoke-SalesforceCheck
exit 1
}
# Validate that either file or code is provided
if (-not $fl -and -not $code) {
Write-Host "Error: Must specify either -fl or -code parameter" -ForegroundColor Red
Write-Host ""
Write-Host "Usage examples:" -ForegroundColor Yellow
Write-Host " .\sf-apex-run.ps1 -fl `"scripts/setup.apex`"" -ForegroundColor Gray
Write-Host " .\sf-apex-run.ps1 -code `"System.debug('Hello World');`"" -ForegroundColor Gray
Write-Host ""
Write-Host "Use -hp for detailed usage information." -ForegroundColor Yellow
exit 1
}
# Validate that both file and code aren't provided
if ($fl -and $code) {
Write-Host "Error: Cannot specify both -fl and -code parameters" -ForegroundColor Red
exit 1
}
# If file is specified, validate it exists and read content
if ($fl) {
if (-not (Test-Path $fl)) {
Write-Host "Error: Apex file not found: $fl" -ForegroundColor Red
exit 1
}
try {
$apexContent = Get-Content -Path $fl -Raw
Write-Host "Using Apex file: $fl" -ForegroundColor Green
if ($ve) {
Show-CodePreview $apexContent "from file: $fl"
}
} catch {
Write-Host "Error reading Apex file: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}
} else {
$apexContent = $code
Write-Host "Using inline Apex code" -ForegroundColor Green
if ($ve) {
Show-CodePreview $apexContent "inline"
}
}
# Build the sf command
$sfArgs = @("apex", "run")
# Add target org if specified
if ($to) {
$sfArgs += "--target-org"
$sfArgs += $to
Write-Host "Target org: $to" -ForegroundColor Cyan
}
# Note: sf apex run doesn't support --verbose flag
# Verbose mode only affects our script's output (code preview)
# Display execution info
Write-Host ""
Write-Host "🚀 Executing Anonymous Apex" -ForegroundColor Blue
Write-Host "============================" -ForegroundColor Blue
# Create a temporary file for the Apex content if needed
$tempFile = $null
if ($code) {
$tempFile = [System.IO.Path]::GetTempFileName() + ".apex"
try {
Set-Content -Path $tempFile -Value $apexContent -Encoding UTF8
$sfArgs += "--file"
$sfArgs += $tempFile
} catch {
Write-Host "Error creating temporary file: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}
} else {
$sfArgs += "--file"
$sfArgs += $fl
}
# Display the command being run (without showing temp file path)
$displayArgs = $sfArgs -replace [regex]::Escape($tempFile), '<temp-file>'
Write-Host ""
Write-Host "Executing: sf $($displayArgs -join ' ')" -ForegroundColor Gray
Write-Host ""
# Execute the command
try {
$startTime = Get-Date
& sf @sfArgs
$exitCode = $LASTEXITCODE
$endTime = Get-Date
$duration = $endTime - $startTime
Write-Host ""
Write-Host "⏱️ Execution completed in $($duration.TotalSeconds.ToString('F2')) seconds" -ForegroundColor Gray
if ($exitCode -eq 0) {
Write-Host ""
Write-Host "✅ Anonymous Apex executed successfully!" -ForegroundColor Green
if ($ve) {
Write-Host "💡 Check the output above for any System.debug() statements" -ForegroundColor Yellow
}
} else {
Write-Host ""
Write-Host "❌ Apex execution failed with exit code: $exitCode" -ForegroundColor Red
Write-Host "💡 Check compilation errors or runtime exceptions above" -ForegroundColor Yellow
# Clean up temp file before exiting
if ($tempFile -and (Test-Path $tempFile)) {
Remove-Item $tempFile -Force -ErrorAction SilentlyContinue
}
exit $exitCode
}
} catch {
Write-Host "Error executing sf command: $($_.Exception.Message)" -ForegroundColor Red
# Clean up temp file before exiting
if ($tempFile -and (Test-Path $tempFile)) {
Remove-Item $tempFile -Force -ErrorAction SilentlyContinue
}
exit 1
} finally {
# Clean up temporary file
if ($tempFile -and (Test-Path $tempFile)) {
Remove-Item $tempFile -Force -ErrorAction SilentlyContinue
}
}