239 lines
6.9 KiB
PowerShell
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
|
|
}
|
|
}
|