Transpilers/Define.psx.ps1
<# .SYNOPSIS Defines a variable .DESCRIPTION Defines a variable using a value provided at build time. .EXAMPLE { [Define(Value={Get-Random})]$RandomNumber }.Transpile() .EXAMPLE { [Define(Value={$global:ThisValueExistsAtBuildTime})]$MyVariable }.Transpile() #> param( # The value to define. # When this value is provided within an attribute as a ScriptBlock, the ScriptBlock will be run at build time. [Parameter(Mandatory)] [AllowNull()] [PSObject] $Value, # The variable the definition will be applied to. [Parameter(Mandatory,ParameterSetName='VariableAST', ValueFromPipeline)] [Management.Automation.Language.VariableExpressionast] $VariableAst, # The name of the variable. If define is applied as an attribute of a variable, this does not need to be provided. [Alias('Name')] [string] $VariableName ) begin { function EmbedString { param($str) { if ($val.Contains('$')) { if ($val -match '[\r\n]') { '"@' + [Environment]::NewLine + $val.Replace('"', '`"') + [Environment]::NewLine + '@"' } else { '"' + $val.Replace('"', '`"') + '"' } } else { if ($val -match '[\r\n]') { "'@" + [Environment]::NewLine + $val.Replace("'", "''") + [Environment]::NewLine + "@'" } else { "'" + $val.Replace("'", "''") + "'" } } } } } process { # Get the value we want to define $definedValue = # A null will become if ($value -eq $null) { '$null' # $null } # a string elseif ($value -is [string]) { EmbedString $value # will be embedded } # a boolean elseif ($value -is [bool]) { if ($value) { '$true' # will become $true } else { '$false' # or $false } } # a primitive elseif ($value.GetType().IsPrimitive) { # will be embedded and typecast "[$($value.GetType().Name)]$value" } # a [ScriptBlock] elseif ($value -is [ScriptBlock]) { "{$value}" # will be embedded within {} } # a [timespan] elseif ($value -is [Timespan]) { # can be cast from it's stringified value "[Timespan]'$value'" } # a [DateTime] elseif ($value -is [DateTime]) { # can be cast from a standardized string value "[DateTime]'$($value.ToString('o'))'" } # Otherwise, else { # embed the variable as JSON "@' $($value | ConvertTo-Json -Depth 100) '@ | ConvertFrom-Json" } if ($PSCmdlet.ParameterSetName -eq 'ScriptBlock') { if (-not $VariableName) { Write-Error "Must provide a -VariableName" return } } if ($PSCmdlet.ParameterSetName -eq 'VariableAst') { [ScriptBlock]::Create('$' + $VariableAst.VariablePath.ToString() + ' = ' + $definedValue) } elseif ($PSCmdlet.ParameterSetName -eq 'ScriptBlock') { $blockName = if ($ScriptBlock.Ast.DynamicParamBlock) { "dynamicParam" } elseif ($scriptblock.Ast.beignBlock.Statements) { "begin" } elseif ($scriptBlock.Ast.processblock.Statements) { "process" } else { ''} $toCreate = if ($blockName) { "$blockName {`$$VariableName =$definedValue }" } else { "param() `$$VariableName = $definedValue" } [scriptblock]::Create($toCreate), $scriptblock | Join-PipeScript } } |