-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathImport-MBModulePrivateFunction.ps1
More file actions
145 lines (123 loc) · 7.21 KB
/
Copy pathImport-MBModulePrivateFunction.ps1
File metadata and controls
145 lines (123 loc) · 7.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
function Import-MBModulePrivateFunction {
<#
.SYNOPSIS
Retrieves private module function definitions and recreates them in your modulebuild based project.
.DESCRIPTION
Retrieves private module function definitions and recreates them in your modulebuild based project. This can be used to either upgrade modulebuild for a project or convert an existing module to start using modulebuild. This function will load and then unload the module to work its magic. 'Private' functions are determined by excluding exported functions and using AST to filter out all function definitions in files within the module folder that are not embedded in other functions. This function will not overwrite any existing private function file of the same name.
.PARAMETER Path
Specifies the path to a buildenvironment.json file for an existing modulebuild project.
.PARAMETER ModulePath
An existing module path to target. Must be a psd1 or psm1 file.
.PARAMETER Name
Function name to import. If none are specified then all functions will be imported.
.PARAMETER DoNotAddCBH
Do not attempt to find and insert comment based help into the function. Default for private functions is to skip CBH insertion.
.PARAMETER ExcludePaths
Paths within the root of your module source which will be ignored in this import.
.PARAMETER ExcludeFiles
Files, in regex pattern format, that will be ignored in this import.
.LINK
https://github.com/zloeber/ModuleBuild
.EXAMPLE
Import-MBModulePrivateFunction -ModulePath 'C:\Temp\PSCloudFlare\PSCloudFlare.psd1'
Finds all the functions that are in the module source but not exported and prompts for each of them to recreate them as individual ps1 files within your ModuleBuild src\private directory.
.NOTES
This only applies to modules of the type 'Script'. Be very careful before importing everything as any wayward functions might get imported and bloat your resulting module needlessly.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueSwitchParameter", "",Scope="function",Target="Import-MBModulePrivateFunction",Justification="Not adding CBH by default is actually useful.")]
[CmdletBinding( SupportsShouldProcess = $True, ConfirmImpact = 'High' )]
param(
[parameter(Position = 0, ValueFromPipeline = $TRUE)]
[String]$Path,
[parameter(Position = 1, ValueFromPipeline = $TRUE, Mandatory = $TRUE)]
[String]$ModulePath,
[parameter(Position = 2)]
[String]$Name = '*',
[parameter(Position = 3)]
[Switch]$DoNotAddCBH = $true,
[parameter(Position = 4)]
[string[]]$ExcludePaths = @('temp','build','.git','.vscode','docs','release','plaster'),
[parameter(Position = 5)]
[string[]]$ExcludeFiles = @('.*\.buildenvironment.ps1','.*\.build.ps1','Build\.ps1','Install\.ps1','PreLoad\.ps1','PostLoad\.ps1','.*\.tests\.ps1','.*\.test\.ps1')
)
begin {
if ($script:ThisModuleLoaded -eq $true) {
Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
}
if ($ModulePath -notmatch '.*\.[psm1|psd1]') {
throw 'Please provide the full path to a psm1 or psd1 file to process'
}
$ExFiles = $ExcludeFiles | Convert-MBArrayToRegex -DoNotEscape
try {
$LoadedModule = Import-Module -Name $ModulePath -Force -PassThru
$PublicFunctions = $LoadedModule.ExportedCommands.Keys
$SourceModuleBasePath = Resolve-Path -Path (Split-path $ModulePath)
Remove-Module -Name $LoadedModule.Name -Force
Write-Verbose "Exported Functions for module = $PublicFunctions"
}
catch {
throw "Unable to import $ModulePath"
}
Write-Verbose "Source Module Base Path = $SourceModuleBasePath"
$AllSourcefiles = @(Get-ChildItem -Path $SourceModuleBasePath -Directory -Exclude $ExcludePaths | Get-ChildItem -File -Recurse) | Where-Object {($_.Name -notmatch $ExFiles) -and (@('.ps1','.psm1') -contains $_.extension)}
$AllSourcefiles += @(Get-ChildItem -Path $SourceModuleBasePath -File | Where-Object {(@('.ps1','.psm1') -contains $_.extension) -and ($_.Name -notmatch $ExFiles)})
$PSBoundParameters.Confirm = $true
$PrivateFunctions = @()
}
process {
# If no build file path was specified take a few guesses
if ([string]::IsNullOrEmpty($Path)) {
$Path = (Get-ChildItem -File -Filter "*.buildenvironment.json" -Path '.\','..\','.\build\' | Select-Object -First 1).FullName
if ([string]::IsNullOrEmpty($Path)) {
throw 'Unable to locate a *.buildenvironment.json file to parse!'
}
}
if (-not (Test-Path $Path)) {
throw "Unable to find the file: $Path"
}
try {
$LoadedBuildEnv = Get-Content $Path | ConvertFrom-Json
$ProjectPath = Split-Path (Split-Path $Path)
$PrivateSrcPath = Join-Path $ProjectPath $LoadedBuildEnv.PrivateFunctionSource
Write-Verbose "Destination Private Function Base Path = $PrivateSrcPath"
}
catch {
throw "Unable to load the build file in $Path"
}
# Gather all the nonembedded function definitions that are not defined as public functions
Foreach ($SourceFile in $AllSourceFiles) {
Write-Verbose "Processing $($SourceFile.FullName)"
try {
Get-Content -Path $SourceFile.FullName | Get-MBFunction | ForEach-Object {
if ((-not $_.IsEmbedded) -and ($PublicFunctions -notcontains $_.Name) -and ($_.Name -like $Name)) {
Write-Verbose "Adding private function definition for $($_.Name)"
$PrivateFunctions += $_ | Select-Object Name,Definition,@{n='SourcePath';e={$SourceFile.FullName}}
}
}
}
catch {
Write-Warning "Unable to process $($SourceFile.FullName), there may be errors in this script."
}
}
# Process our candidate private functions
Foreach ($PrivFunc in $PrivateFunctions) {
$DestPath = Join-Path $PrivateSrcPath "$($PrivFunc.Name).ps1"
# Only attempt to copy over new function files, skip if the name already exists in the destination path
if (-not (Test-Path $DestPath)) {
if ($pscmdlet.ShouldProcess("$($PrivFunc.Name) from file $($PrivFunc.SourcePath)", "Import private function $($PrivFunc.Name) to the project $($LoadedBuildEnv.ModuleToBuild)?")) {
if ($DoNotAddCBH) {
# Skipping comment based help insertion
$PrivFunc.definition | Out-File -FilePath $DestPath -Encoding:utf8 -Confirm:$false
}
else {
# inserting comment based help if it doesn't already exist.
$PrivFunc.definition | Add-MBMissingCBH | Out-File -FilePath $DestPath -Encoding:utf8 -Confirm:$false
}
}
}
else {
Write-Warning "The following private function already exists: $DestPath"
}
}
}
}