Skip to content

Commit 7a40d0d

Browse files
committed
A version of ConvertTo-Script that packs modules as ps1
1 parent 4bafe09 commit 7a40d0d

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed

Source/Public/ConvertTo-Script.ps1

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
using namespace System.Management.Automation.Language
2+
using namespace System.Collections.Generic
3+
4+
function ConvertTo-Script {
5+
<#
6+
.SYNOPSIS
7+
A Script Generator which converts a module to a script
8+
.DESCRIPTION
9+
ConvertTo-Script takes a script module (which may include dotnet assemblies),
10+
and generates a script file with the module and libraries embedded and ready to run.
11+
12+
You should provide the name of a function from the module that will be invoked when the script is run.
13+
14+
In this way you can package any module into a script which invokes a specific command in that module.
15+
16+
This function never outputs any TextReplacements.
17+
#>
18+
[CmdletBinding()]
19+
[OutputType([TextReplacement])]
20+
param(
21+
# The AST of the script module to convert to a script
22+
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
23+
[Alias("Ast")]
24+
[Ast]$ScriptModule,
25+
26+
# The name of a function in the module to invoke when the script is run
27+
[Parameter(Mandatory)]
28+
[string]$FunctionName,
29+
30+
# The path to the script module to convert
31+
# This is used to find the module manifest,
32+
# But the the script will be saved in the same location
33+
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
34+
[string]$Path
35+
)
36+
begin {
37+
Write-Debug " ENTER: ConvertTo-Script BEGIN $Path $FunctionName"
38+
class ParamBlockExtractor : AstVisitor {
39+
[string]$ParamBlock
40+
[string]$FunctionName
41+
[CommentHelpInfo]$HelpInfo
42+
43+
[AstVisitAction] VisitParamBlock([ParamBlockAst]$ast) {
44+
if ($ast.Parameters) {
45+
$this.ParamBlock = @(@($ast.Attributes.Extent.Text) + $ast.Extent.Text) -join "`n"
46+
}
47+
return [AstVisitAction]::StopVisit
48+
}
49+
50+
[AstVisitAction] VisitFunctionDefinition([FunctionDefinitionAst]$ast) {
51+
if ($ast.Name -ne $this.FunctionName) {
52+
return [AstVisitAction]::SkipChildren
53+
}
54+
$this.HelpInfo = $ast.GetHelpContent()
55+
return [AstVisitAction]::Continue
56+
}
57+
}
58+
Write-Debug " EXIT: ConvertTo-Script BEGIN"
59+
}
60+
process {
61+
Write-Debug " ENTER: ConvertTo-Script PROCESS $Path $FunctionName"
62+
$Visitor = [ParamBlockExtractor]@{
63+
FunctionName = $FunctionName
64+
}
65+
$ScriptModule.Visit($Visitor)
66+
67+
Write-Debug " Parse Module Manifest: $Path"
68+
$ModuleManifest = [IO.Path]::ChangeExtension($Path, '.psd1')
69+
Write-Debug " Parse Module Manifest: $ModuleManifest"
70+
$Manifest = ConvertFrom-Metadata $ModuleManifest
71+
72+
if (!$Visitor.ParamBlock) {
73+
Write-Error "ConvertTo-Script: Could not find function $FunctionName in $Path"
74+
}
75+
76+
Push-Location (Split-Path $ModuleManifest -Parent)
77+
if (Test-Path "$FunctionName.ps1") {
78+
Write-Warning "Overwriting existing script $FunctionName.ps1"
79+
}
80+
@(
81+
@"
82+
<#PSScriptInfo
83+
.VERSION 0.0.0
84+
.GUID $([guid]::newguid())
85+
.AUTHOR anonymous
86+
.COMPANYNAME
87+
.COPYRIGHT
88+
.TAGS
89+
.LICENSEURI
90+
.PROJECTURI
91+
.ICONURI
92+
.EXTERNALMODULEDEPENDENCIES
93+
.REQUIREDSCRIPTS
94+
.EXTERNALSCRIPTDEPENDENCIES
95+
.RELEASENOTES
96+
.PRIVATEDATA
97+
#>
98+
99+
"@
100+
$Visitor.HelpInfo.GetCommentBlock()
101+
$Visitor.ParamBlock
102+
"`n"
103+
@(
104+
if ($Manifest.RequiredAssemblies) {
105+
Get-ChildItem $Manifest.RequiredAssemblies
106+
}
107+
Get-Item $Path
108+
) | CompressToBase64 -ExpandScriptName ImportBase64Module
109+
"$FunctionName @PSBoundParameters"
110+
) | Set-Content "$FunctionName.ps1"
111+
112+
Update-ScriptFileInfo "$FunctionName.ps1" -Version $Manifest.ModuleVersion -Author $Manifest.Author -CompanyName $Manifest.CompanyName -Copyright $Manifest.Copyright -Tags $Manifest.PrivateData.PSData.Tags -ProjectUri $Manifest.PrivateData.PSData.ProjectUri -LicenseUri $Manifest.PrivateData.PSData.LicenseUri -IconUri $Manifest.PrivateData.PSData.IconUri -ReleaseNotes $Manifest.PrivateData.PSData.ReleaseNotes
113+
114+
Pop-Location
115+
Write-Debug " EXIT: ConvertTo-Script PROCESS"
116+
}
117+
}
118+

0 commit comments

Comments
 (0)