Skip to content

Commit 7923843

Browse files
author
James Brundage
committed
Include - Allowing Including URLs (Fixes #481)
1 parent 9371562 commit 7923843

File tree

1 file changed

+79
-9
lines changed

1 file changed

+79
-9
lines changed

Transpilers/Include.psx.ps1

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,23 @@
1616
{
1717
[Include('*-*.ps1')]$psScriptRoot
1818
} | .>PipeScript
19+
.EXAMPLE
20+
{
21+
[Include('https://pssvg.start-automating.com/Examples/PowerShellChevron.svg')]$PSChevron
22+
} | .>PipeScript
1923
#>
20-
[ValidateScript({
21-
if ($_ -is [Management.Automation.Language.CommandAst]) {
22-
return $_.CommandsElements[0].Value -in 'include','includes'
24+
[ValidateScript({
25+
$validating = $_
26+
if ($validating -is [Management.Automation.Language.CommandAst]) {
27+
return $validating.CommandElements[0].Value -in 'include','includes'
2328
}
2429
})]
2530
[Alias('Includes')]
2631
param(
2732
# The File Path to Include
28-
[Parameter(Mandatory,Position=0)]
33+
[Parameter(Mandatory,ParameterSetName='VariableAST',Position=0)]
34+
[Parameter(ParameterSetName='CommandAst',Position=0)]
35+
[Alias('FullName','Uri','Url')]
2936
[string]
3037
$FilePath,
3138

@@ -42,11 +49,16 @@ $Passthru,
4249
[string[]]
4350
$Exclude = '\.[^\.]+\.ps1$',
4451

52+
# The variable that include will be applied to.
53+
# If including files with wildcards, this will be the base path.
54+
# Otherwise, this variable will be assigned to the included value.
4555
[Parameter(Mandatory,ParameterSetName='VariableAST', ValueFromPipeline)]
4656
[Management.Automation.Language.VariableExpressionast]
4757
$VariableAst,
4858

4959

60+
# The CommandAST.
61+
# This is provided by the transpiler when include is used as a keyword.
5062
[Parameter(Mandatory,ParameterSetName='CommandAst',ValueFromPipeline)]
5163
[Management.Automation.Language.CommandAst]
5264
$CommandAst
@@ -74,14 +86,22 @@ process {
7486
$ExecutionContext.SessionState.PSVariable.Set($paramName, $mySentence.Parameters[$paramName])
7587
}
7688
}
89+
90+
if ($mySentence.ArgumentList -and -not $FilePath) {
91+
$FilePath = $mySentence.ArgumentList[0]
92+
}
7793
}
7894

7995
# Determine the command we would be including (relative to the current path)
8096
$includingCommand = $ExecutionContext.SessionState.InvokeCommand.GetCommand($FilePath, 'All')
8197
if (-not $includingCommand) { # if we could not determine the command, we may need to error out.
82-
if (-not $FilePath.Contains('*')) {
83-
Write-Error "Could not resolve $($FilePath)"
84-
return
98+
if ($FilePath -match '^https?://') {
99+
$includingUrl = $FilePath -as [uri]
100+
} else {
101+
if (-not $FilePath.Contains('*')) {
102+
Write-Error "Could not resolve $($FilePath). Must be a command, path, or URI."
103+
return
104+
}
85105
}
86106
}
87107

@@ -167,6 +187,52 @@ if ($Passthru) { [Environment]::NewLine + "`${$($includingCommand.Name)}"}
167187
} elseif ($includingCommand) {
168188
IncludeFileContents $includingCommand.Source
169189
}
190+
elseif ($includingUrl) {
191+
$webResponse = Invoke-WebRequest -Uri $includingUrl
192+
if ($webResponse.Content -is [string]) {
193+
$restResponse = Invoke-RestMethod -Uri $includingUrl
194+
if (
195+
(
196+
($restResponse -is [PSObject]) -or
197+
($restResponse -is [Object[]])
198+
) -and (
199+
-not ($webResponse.Content -as [xml])
200+
) -and (
201+
$restResponse -isnot [string]
202+
)
203+
) {
204+
[ScriptBlock]::Create((@(
205+
"@'"
206+
$($restResponse | ConvertTo-Json -Depth 100)
207+
"'@ |"
208+
" ConvertFrom-JSON"
209+
) -join [Environment]::NewLine))
210+
}
211+
else {
212+
if ($restResponse -is [string] -and $(
213+
$restScript = try { [scriptblock]::Create($restResponse) } catch { $null }
214+
$restScript
215+
)) {
216+
$restScript
217+
}
218+
else {
219+
[ScriptBlock]::Create((@(
220+
"$(if ($webResponse.Content -as [xml]) { '[xml]'})@'"
221+
$(if ($restResponse -is [xml]) { $restResponse.OuterXML } else { $restResponse })
222+
"'@"
223+
) -join [Environment]::NewLine))
224+
}
225+
}
226+
} elseif ($webResponse.Content -is [byte[]]) {
227+
[ScriptBlock]::Create(
228+
"@'" + [Environment]::NewLine +
229+
[Convert]::ToBase64String(
230+
$webResponse.Content,
231+
'InsertLineBreaks'
232+
) + [Environment]::NewLine +
233+
"'@")
234+
}
235+
}
170236

171237
if ($psCmdlet.ParameterSetName -eq 'ScriptBlock' -or
172238
$VariableAst.VariablePath -match '^null$') {
@@ -176,9 +242,13 @@ if ($psCmdlet.ParameterSetName -eq 'ScriptBlock' -or
176242
$includedScript
177243
}
178244

179-
} elseif ($VariableAst.VariablePath -and $includingCommand) {
245+
} elseif ($VariableAst.VariablePath -and $IncludedScript) {
180246
[ScriptBlock]::Create("$($VariableAst) = $IncludedScript")
181-
} elseif ($VariableAst.VariablePath -notmatch '^null$') {
247+
}
248+
elseif ($CommandAst) {
249+
$IncludedScript
250+
}
251+
elseif ($VariableAst.VariablePath -notmatch '^null$') {
182252
[ScriptBlock]::Create(@"
183253
:ToIncludeFiles foreach (`$file in (Get-ChildItem -Path "$($VariableAst)" -Filter "$FilePath" -Recurse)) {
184254
if (`$file.Extension -ne '.ps1') { continue } # Skip if the extension is not .ps1

0 commit comments

Comments
 (0)