1+ <#
2+ . SYNOPSIS
3+ defines a variable
4+ . DESCRIPTION
5+ Defines a variable using a value provided during a build
6+ . EXAMPLE
7+ {
8+ [Define(Value={Get-Random})]$RandomNumber
9+ }.Transpile()
10+ . EXAMPLE
11+ {
12+ [Define(Value={$global:ThisValueExistsAtBuildTime})]$MyVariable
13+ }.Transpile()
14+ #>
15+ param (
16+ # The value to define.
17+ # When this value is provided within an attribute as a ScriptBlock, the ScriptBlock will be run at build time.
18+ [Parameter (Mandatory )]
19+ [AllowNull ()]
20+ [PSObject ]
21+ $Value ,
22+
23+ # The variable the definition will be applied to.
24+ [Parameter (Mandatory , ParameterSetName = ' VariableAST' , ValueFromPipeline )]
25+ [Management.Automation.Language.VariableExpressionast ]
26+ $VariableAst ,
27+
28+ # A scriptblock the definition will be applied to
29+ [Parameter (Mandatory , ParameterSetName = ' ScriptBlock' , ValueFromPipeline )]
30+ [scriptblock ]
31+ $ScriptBlock = {},
32+
33+ # The name of the variable. If define is applied as an attribute of a variable, this does not need to be provided.
34+ [Alias (' Name' )]
35+ [string ]
36+ $VariableName
37+ )
38+
39+ begin {
40+ function EmbedString {
41+ param ($str ) {
42+ if ($val.Contains (' $' )) {
43+ if ($val -match ' [\r\n]' ) {
44+ ' "@' + [Environment ]::NewLine + $val.Replace (' "' , ' `"' ) + [Environment ]::NewLine + ' @"'
45+ } else {
46+ ' "' + $val.Replace (' "' , ' `"' ) + ' "'
47+ }
48+ } else {
49+ if ($val -match ' [\r\n]' ) {
50+ " '@" + [Environment ]::NewLine + $val.Replace (" '" , " ''" ) + [Environment ]::NewLine + " @'"
51+ } else {
52+ " '" + $val.Replace (" '" , " ''" ) + " '"
53+ }
54+ }
55+ }
56+ }
57+ }
58+
59+ process {
60+ # Get the value we want to define
61+ $definedValue =
62+ # A null will become
63+ if ($value -eq $null ) {
64+ ' $null' # $null
65+ }
66+ # a string
67+ elseif ($value -is [string ]) {
68+ EmbedString $value # will be embedded
69+ }
70+ # a boolean
71+ elseif ($value -is [bool ]) {
72+ if ($value ) {
73+ ' $true' # will become $true
74+ }
75+ else {
76+ ' $false' # or $false
77+ }
78+ }
79+ # a primitive
80+ elseif ($value.GetType ().IsPrimitive) {
81+ # will be embedded and typecast
82+ " [$ ( $value.GetType ().Name) ]$value "
83+ }
84+ # a [ScriptBlock]
85+ elseif ($value -is [ScriptBlock ]) {
86+ " {$value }" # will be embedded within {}
87+ }
88+ # a [timespan]
89+ elseif ($value -is [Timespan ]) {
90+ # can be cast from it's stringified value
91+ " [Timespan]'$value '"
92+ }
93+ # a [DateTime]
94+ elseif ($value -is [DateTime ]) {
95+ # can be cast from a standardized string value
96+ " [DateTime]'$ ( $value.ToString (' o' )) '"
97+ }
98+ # Otherwise,
99+ else {
100+ # embed the variable as JSON
101+ " @'
102+ $ ( $value | ConvertTo-Json - Depth 100 )
103+ '@ | ConvertFrom-Json"
104+ }
105+
106+ if ($PSCmdlet.ParameterSetName -eq ' ScriptBlock' ) {
107+ if (-not $VariableName ) {
108+ Write-Error " Must provide a -VariableName"
109+ return
110+ }
111+ }
112+
113+
114+ if ($PSCmdlet.ParameterSetName -eq ' VariableAst' ) {
115+ [ScriptBlock ]::Create(' $' + $VariableAst.VariablePath.ToString () + ' = ' + $definedValue )
116+ }
117+ elseif ($PSCmdlet.ParameterSetName -eq ' ScriptBlock' ) {
118+ $blockName =
119+ if ($ScriptBlock.Ast.DynamicParamBlock ) {
120+ " dynamicParam"
121+ } elseif ($scriptblock.Ast.beignBlock.Statements ) {
122+ " begin"
123+ } elseif ($scriptBlock.Ast.processblock.Statements ) {
124+ " process"
125+ } else {
126+ " "
127+ }
128+ if ($blockName ) {
129+ [ScriptBlock ]::Create(" $blockName {'$' + $VariableName + ' = ' + $definedValue }" ), $ScriptBlock | Join-PipeScript
130+ }
131+ else {
132+ [ScriptBlock ]::Create(' $' + $VariableName + ' = ' + $definedValue ), $ScriptBlock | Join-PipeScript
133+ }
134+ }
135+ }
0 commit comments