Skip to content

Commit 4514465

Browse files
Merge pull request #92 from StartAutomating/PipeScriptImprovements
Pipe script improvements
2 parents 23f4533 + dd541c0 commit 4514465

37 files changed

+368
-194
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
## 0.0.5
2+
* New Language Features:
3+
* PipedAssignment (#88)
4+
* Command Fixes:
5+
* Invoke-PipeScript now defaults unmapped files to treating them as PowerShell / PipeScript (#86)
6+
* Improved Transpilers:
7+
* .>PipeScript.Inline now supports -StartPattern/-EndPattern (#85)
8+
* Inline Transpilers now use -StartPattern/-EndPattern (#85)
9+
* Inline PipeScript Support for New Languages
10+
* .>Inline.PSD1 (#89)
11+
* .>Inline.XML now handles .PS1XML (#91)
12+
---
13+
114
## 0.0.4
215
* New Transpilers:
316
* .>RegexLiteral (#77)

Invoke-PipeScript.ps1

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -253,39 +253,34 @@
253253
# predetermine the output path
254254
$outputPath = $($Command.Source -replace $IsSourceGenerator, '.${ext}')
255255
# and attempt to find a transpiler.
256-
$foundTranspiler = Get-Transpiler -CouldPipe $Command
256+
$foundTranspiler = Get-Transpiler -CouldPipe $Command -ValidateInput $Command -ErrorAction Ignore
257+
257258

258259
# Push into the location of the file, so the current working directory will be accurate for any inline scripts.
259260
Push-Location ($command.Source | Split-Path)
260261

261262
# Get the output from the source generator.
262263
$pipescriptOutput =
263264
if ($foundTranspiler) { # If we found transpilers
264-
foreach ($ft in $foundTranspiler) {
265-
if ($(
266-
$eap = $ErrorActionPreference
267-
$ErrorActionPreference = 'ignore'
268-
# ensure they are valid
269-
$ft.ExtensionCommand.Validate($Command, $true)
270-
$ErrorActionPreference = $eap
271-
)) {
272-
# and run the transpiler.
273-
274-
$null =
275-
New-Event -SourceIdentifier 'PipeScript.SourceGenerator.Start' -MessageData ([PSCustomObject][Ordered]@{
276-
Transpiler = $ft.ExtensionCommand
277-
SourcePath = $command.Source
278-
})
279-
280-
$transpilerOutput = $command | & $ft.ExtensionCommand
281-
282-
$null =
283-
New-Event -SourceIdentifier 'PipeScript.SourceGenerator.Stop' -MessageData ([PSCustomObject][Ordered]@{
284-
Transpiler = $ft.ExtensionCommand
285-
TranspilerOutput = $transpilerOutput
286-
SourcePath = $command.Source
287-
})
288-
265+
foreach ($ft in $foundTranspiler) {
266+
# run them.
267+
268+
$null =
269+
New-Event -SourceIdentifier 'PipeScript.SourceGenerator.Start' -MessageData ([PSCustomObject][Ordered]@{
270+
Transpiler = $ft.ExtensionCommand
271+
SourcePath = $command.Source
272+
})
273+
274+
$transpilerOutput = $command | & $ft.ExtensionCommand
275+
276+
$null =
277+
New-Event -SourceIdentifier 'PipeScript.SourceGenerator.Stop' -MessageData ([PSCustomObject][Ordered]@{
278+
Transpiler = $ft.ExtensionCommand
279+
TranspilerOutput = $transpilerOutput
280+
SourcePath = $command.Source
281+
})
282+
283+
$transpilerOutput =
289284
# If the transpiler returned a [ScriptBlock]
290285
if ($transpilerOutput -is [Scriptblock]) {
291286
# recursively invoke.
@@ -295,9 +290,13 @@
295290
# otherwise, return the output of the transpiler.
296291
$transpilerOutput
297292
}
298-
break
293+
294+
# If the transpiler had output,
295+
if ($transpilerOutput) {
296+
$transpilerOutput # use that output
297+
break # and stop processing additional transpilers.
299298
}
300-
}
299+
}
301300
} else {
302301
# If we did not find a transpiler, treat the source code as PipeScript/PowerShell.
303302
$fileScriptBlock =
@@ -317,8 +316,12 @@
317316
}
318317

319318
if (-not $fileScriptBlock) { return }
320-
$InvokePipeScriptParameters.Command = $fileScriptBlock
321-
Invoke-PipeScript @InvokePipeScriptParameters
319+
if ($command.Source -match '\.psm{0,1}1{0,1}$') {
320+
$fileScriptBlock
321+
} else {
322+
$InvokePipeScriptParameters.Command = $fileScriptBlock
323+
Invoke-PipeScript @InvokePipeScriptParameters
324+
}
322325
}
323326

324327
# Now that the source generator has finished running, we can Pop-Location.

PipeScript.psd1

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
@{
2-
ModuleVersion = '0.0.4'
1+
@{
2+
ModuleVersion = '0.0.5'
33
Description = 'An Extensible Transpiler for PowerShell (and anything else)'
44
RootModule = 'PipeScript.psm1'
55
PowerShellVersion = '4.0'
@@ -17,6 +17,19 @@
1717

1818
Tags = 'PipeScript','PowerShell', 'Transpilation', 'Compiler'
1919
ReleaseNotes = @'
20+
## 0.0.5
21+
* New Language Features:
22+
* PipedAssignment (#88)
23+
* Command Fixes:
24+
* Invoke-PipeScript now defaults unmapped files to treating them as PowerShell / PipeScript (#86)
25+
* Improved Transpilers:
26+
* .>PipeScript.Inline now supports -StartPattern/-EndPattern (#85)
27+
* Inline Transpilers now use -StartPattern/-EndPattern (#85)
28+
* Inline PipeScript Support for New Languages
29+
* .>Inline.PSD1 (#89)
30+
* .>Inline.XML now handles .PS1XML (#91)
31+
---
32+
2033
## 0.0.4
2134
* New Transpilers:
2235
* .>RegexLiteral (#77)
@@ -60,4 +73,4 @@ Initial Commit.
6073
'@
6174
}
6275
}
63-
}
76+
}

PipeScript.tests.ps1

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,34 @@ describe PipeScript {
1717
}
1818
}
1919

20+
context 'Inline PipeScript' {
21+
it 'Can be embedded in another language (to transmute source code or documents)' {
22+
.> {
23+
$CSharpLiteral = @'
24+
namespace TestProgram/*{Get-Random}*/ {
25+
public static class Program {
26+
public static string Hello() {
27+
string helloMessage = /*{
28+
'"hello"', '"hello world"', '"hey there"', '"howdy"' | Get-Random
29+
}*/ string.Empty;
30+
return helloMessage;
31+
}
32+
}
33+
}
34+
'@
35+
36+
[OutputFile(".\HelloWorld.ps1.cs")]$CSharpLiteral
37+
}
38+
39+
$AddedFile = .> .\HelloWorld.ps1.cs
40+
$addedType = Add-Type -TypeDefinition (Get-Content $addedFile.FullName -Raw) -PassThru
41+
$addedType::Hello() | Should -belike 'H*'
42+
43+
Remove-Item .\HelloWorld.ps1.cs
44+
Remove-Item $AddedFile.FullName
45+
}
46+
}
47+
2048
it 'Can transpile a scriptblock that is preceeded by the name of a transpiler' {
2149
Invoke-PipeScript -ScriptBlock {
2250
[bash]{param($msg = 'hello world') $msg}

Transpilers/Core/PipeScript.Inline.psx.ps1

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@
88
99
Inline PipeScript will be embedded within the file (usually in comments).
1010
11-
Anything encountered in a source generator file can be either:
12-
13-
* A Literal String (written directly in the underlying source language)
14-
* A Script Block (written in PowerShell or PipeScript)
15-
16-
This Transpiler takes a sequence of literal strings and script blocks, and constructs the source generation script.
11+
If a Regular Expression can match each section, then the content in each section can be replaced.
1712
#>
1813
param(
1914
# A list of source sections
@@ -24,6 +19,7 @@ $SourceSection,
2419
# A string containing the text contents of the file
2520
[Parameter(Mandatory,ParameterSetName='SourceTextAndPattern')]
2621
[Parameter(Mandatory,ParameterSetName='SourceTextReplace')]
22+
[Parameter(Mandatory,ParameterSetName='SourceStartAndEnd')]
2723
[string]
2824
$SourceText,
2925

@@ -46,35 +42,56 @@ $SourcePattern,
4642
[regex]
4743
$ReplacePattern,
4844

45+
# The Start Pattern.
46+
# This indicates the beginning of what should be considered PipeScript.
47+
# An expression will match everything until -EndPattern
48+
[Parameter(Mandatory,ParameterSetName='SourceStartAndEnd')]
49+
[Alias('StartRegex')]
50+
[Regex]
51+
$StartPattern,
52+
53+
# The End Pattern
54+
# This indicates the end of what should be considered PipeScript.
55+
[Parameter(Mandatory,ParameterSetName='SourceStartAndEnd')]
56+
[Alias('EndRegex')]
57+
[Regex]
58+
$EndPattern,
59+
4960
[Parameter(ParameterSetName='SourceTextReplace')]
61+
[Parameter(ParameterSetName='SourceStartAndEnd')]
5062
[Alias('Replacer')]
5163
[ScriptBlock]
5264
$ReplacementEvaluator,
5365

5466
# If set, will not transpile script blocks.
5567
[Parameter(ParameterSetName='SourceTextAndPattern')]
5668
[Parameter(ParameterSetName='SourceSections')]
69+
[Parameter(ParameterSetName='SourceStartAndEnd')]
70+
[Parameter(ParameterSetName='SourceTextReplace')]
5771
[switch]
5872
$NoTranspile,
5973

6074
# The path to the source file.
6175
[Parameter(ParameterSetName='SourceTextAndPattern')]
6276
[Parameter(ParameterSetName='SourceSections')]
6377
[Parameter(ParameterSetName='SourceTextReplace')]
78+
[Parameter(ParameterSetName='SourceStartAndEnd')]
6479
[string]
6580
$SourceFile,
6681

6782
# A Script Block that will be injected before each inline is run.
6883
[Parameter(ParameterSetName='SourceTextAndPattern')]
6984
[Parameter(ParameterSetName='SourceSections')]
7085
[Parameter(ParameterSetName='SourceTextReplace')]
86+
[Parameter(ParameterSetName='SourceStartAndEnd')]
7187
[ScriptBlock]
7288
$Begin,
7389

7490
# A Script Block that will be piped to after each output.
7591
[Parameter(ParameterSetName='SourceTextAndPattern')]
7692
[Parameter(ParameterSetName='SourceSections')]
7793
[Parameter(ParameterSetName='SourceTextReplace')]
94+
[Parameter(ParameterSetName='SourceStartAndEnd')]
7895
[Alias('Process')]
7996
[ScriptBlock]
8097
$ForeachObject,
@@ -83,6 +100,7 @@ $ForeachObject,
83100
[Parameter(ParameterSetName='SourceTextAndPattern')]
84101
[Parameter(ParameterSetName='SourceSections')]
85102
[Parameter(ParameterSetName='SourceTextReplace')]
103+
[Parameter(ParameterSetName='SourceStartAndEnd')]
86104
[ScriptBlock]
87105
$End
88106
)
@@ -92,7 +110,22 @@ begin {
92110
}
93111

94112
process {
95-
if ($psCmdlet.ParameterSetName -eq 'SourceTextReplace') {
113+
$psParameterSet = $psCmdlet.ParameterSetName
114+
if ($psParameterSet -eq 'SourceStartAndEnd') {
115+
$ReplacePattern = [Regex]::New("
116+
# Match the PipeScript Start
117+
$StartPattern
118+
# Match until the PipeScript end. This will be PipeScript
119+
(?<PipeScript>
120+
(?:.|\s){0,}?(?=\z|$endPattern)
121+
)
122+
# Then Match the PipeScript End
123+
$EndPattern
124+
", 'IgnoreCase, IgnorePatternWhitespace', '00:00:10')
125+
$psParameterSet = 'SourceTextReplace'
126+
}
127+
128+
if ($psParameterSet -eq 'SourceTextReplace') {
96129
$fileText = $SourceText
97130
if (-not $PSBoundParameters["ReplacementEvaluator"]) {
98131
$ReplacementEvaluator = {
@@ -168,7 +201,7 @@ process {
168201
return $ReplacePattern.Replace($fileText, $ReplacementEvaluator)
169202
}
170203

171-
if ($psCmdlet.ParameterSetName -eq 'SourceTextAndPattern') {
204+
if ($psParameterSet -eq 'SourceTextAndPattern') {
172205

173206
$fileText = $SourceText
174207
$foundSpots = @($SourcePattern.Matches($fileText))

Transpilers/Inline/Inline.ATOM.psx.ps1

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,12 @@ begin {
2828
$startRegex = "(?<PSStart>${startComment}\{$Whitespace)"
2929
# * EndRegex ```$whitespace + '}' + $EndComment```
3030
$endRegex = "(?<PSEnd>$Whitespace\}${endComment}\s{0,})"
31-
32-
$sourcePattern = [Regex]::New("(?>$(
33-
$startRegex, $endRegex -join ([Environment]::NewLine + '|' + [Environment]::NewLine)
34-
))", "IgnoreCase, IgnorePatternWhitespace", "00:00:05")
3531
}
3632

3733
process {
3834

3935
$fileInfo = $commandInfo.Source -as [IO.FileInfo]
4036
$fileText = [IO.File]::ReadAllText($fileInfo.Fullname)
4137

42-
.>PipeScript.Inline -SourceFile $CommandInfo.Source -SourceText $fileText -SourcePattern $sourcePattern
38+
.>PipeScript.Inline -SourceFile $CommandInfo.Source -SourceText $fileText -StartPattern $startRegex -EndPattern $endRegex
4339
}

Transpilers/Inline/Inline.Bicep.psx.ps1

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,12 @@ begin {
3535
$startRegex = "(?<PSStart>${IgnoredContext}${startComment}\{$Whitespace)"
3636
# * EndRegex ```$whitespace + '}' + $EndComment + $ignoredContext```
3737
$endRegex = "(?<PSEnd>$Whitespace\}${endComment}\s{0,}${IgnoredContext})"
38-
39-
$sourcePattern = [Regex]::New("(?>$(
40-
$startRegex, $endRegex -join ([Environment]::NewLine + '|' + [Environment]::NewLine)
41-
))", "IgnoreCase, IgnorePatternWhitespace", "00:00:05")
4238
}
4339

4440
process {
4541

4642
$fileInfo = $commandInfo.Source -as [IO.FileInfo]
4743
$fileText = [IO.File]::ReadAllText($fileInfo.Fullname)
4844

49-
.>PipeScript.Inline -SourceFile $CommandInfo.Source -SourceText $fileText -SourcePattern $sourcePattern
45+
.>PipeScript.Inline -SourceFile $CommandInfo.Source -SourceText $fileText -StartPattern $startRegex -EndPattern $endRegex
5046
}

Transpilers/Inline/Inline.CPlusPlus.psx.ps1

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,11 @@ begin {
4040
$startRegex = "(?<PSStart>${IgnoredContext}${startComment}\{$Whitespace)"
4141
# * EndRegex ```$whitespace + '}' + $EndComment + $ignoredContext```
4242
$endRegex = "(?<PSEnd>$Whitespace\}${endComment}\s{0,}${IgnoredContext})"
43-
44-
$sourcePattern = [Regex]::New("(?>$(
45-
$startRegex, $endRegex -join ([Environment]::NewLine + '|' + [Environment]::NewLine)
46-
))", "IgnoreCase, IgnorePatternWhitespace", "00:00:05")
4743
}
4844

4945
process {
5046
$fileInfo = $commandInfo.Source -as [IO.FileInfo]
5147
$fileText = [IO.File]::ReadAllText($fileInfo.Fullname)
5248

53-
.>PipeScript.Inline -SourceFile $CommandInfo.Source -SourceText $fileText -SourcePattern $sourcePattern
49+
.>PipeScript.Inline -SourceFile $CommandInfo.Source -SourceText $fileText -StartPattern $startRegex -EndPattern $endRegex
5450
}

Transpilers/Inline/Inline.CSS.psx.ps1

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,12 @@ begin {
5959
$startRegex = "(?<PSStart>${IgnoredContext}${startComment}\{$Whitespace)"
6060
# * EndRegex ```$whitespace + '}' + $EndComment + $ignoredContext```
6161
$endRegex = "(?<PSEnd>$Whitespace\}${endComment}\s{0,}${IgnoredContext})"
62-
63-
$sourcePattern = [Regex]::New("(?>$(
64-
$startRegex, $endRegex -join ([Environment]::NewLine + '|' + [Environment]::NewLine)
65-
))", "IgnoreCase, IgnorePatternWhitespace", "00:00:05")
6662
}
6763

6864
process {
6965

7066
$fileInfo = $commandInfo.Source -as [IO.FileInfo]
7167
$fileText = [IO.File]::ReadAllText($fileInfo.Fullname)
7268

73-
.>PipeScript.Inline -SourceFile $CommandInfo.Source -SourceText $fileText -SourcePattern $sourcePattern
69+
.>PipeScript.Inline -SourceFile $CommandInfo.Source -SourceText $fileText -StartPattern $startRegex -EndPattern $endRegex
7470
}

Transpilers/Inline/Inline.CSharp.psx.ps1

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,12 @@ begin {
7474
$startRegex = "(?<PSStart>${IgnoredContext}${startComment}\{$Whitespace)"
7575
# * EndRegex ```$whitespace + '}' + $EndComment + $ignoredContext```
7676
$endRegex = "(?<PSEnd>$Whitespace\}${endComment}\s{0,}${IgnoredContext})"
77-
78-
$sourcePattern = [Regex]::New("(?>$(
79-
$startRegex, $endRegex -join ([Environment]::NewLine + '|' + [Environment]::NewLine)
80-
))", "IgnoreCase, IgnorePatternWhitespace", "00:00:05")
8177
}
8278

8379
process {
8480

8581
$fileInfo = $commandInfo.Source -as [IO.FileInfo]
8682
$fileText = [IO.File]::ReadAllText($fileInfo.Fullname)
8783

88-
.>PipeScript.Inline -SourceFile $CommandInfo.Source -SourceText $fileText -SourcePattern $sourcePattern
84+
.>PipeScript.Inline -SourceFile $CommandInfo.Source -SourceText $fileText -StartPattern $startRegex -EndPattern $endRegex
8985
}

0 commit comments

Comments
 (0)