Skip to content

Commit c707748

Browse files
author
James Brundage
committed
Adding Define (Fixes #299)
1 parent f95348a commit c707748

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

Transpilers/Define.psx.ps1

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
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

Comments
 (0)