-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixing parameters and fulfilling promise
- Loading branch information
StartAutomating
authored and
StartAutomating
committed
May 31, 2024
1 parent
e1c598f
commit f607252
Showing
1 changed file
with
118 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
[ValidatePattern('Use[-\.]Module')] | ||
param() | ||
function Use-Module { | ||
|
||
<# | ||
.SYNOPSIS | ||
Uses a module. | ||
.DESCRIPTION | ||
Uses a module. | ||
This can either: | ||
* If present, run a module's `Use` function, method, or script property. | ||
* Otherwise, run a script block in the module's context. | ||
* Run a module's `Use` function, if present | ||
* Call a module's `Use` method, if present | ||
In all cases, the script block should be run in the module's context, using dot-sourcing. | ||
.EXAMPLE | ||
Get-Module PipeScript | Use-Module -ScriptBlock { $myInvocation.MyCommand.ScriptBlock.Module } | ||
#> | ||
[Alias('Use.Module','Module.Use')] | ||
param( | ||
# The name of the module | ||
[Parameter(ValueFromPipeline)] | ||
[Alias('ModuleName')] | ||
[string] | ||
$Name, | ||
|
||
# The script block to use. | ||
[ScriptBlock] | ||
$ScriptBlock = {}, | ||
|
||
# The list of arguments to pass to the script block. | ||
[Parameter(ValueFromRemainingArguments)] | ||
[Alias('Arguments','Args')] | ||
[PSObject[]] | ||
$ArgumentList, | ||
|
||
# Any named parameters to pass to the script block. | ||
[Parameter(ValueFromPipelineByPropertyName)] | ||
[Alias('Parameters')] | ||
[Collections.IDictionary] | ||
$Parameter | ||
) | ||
|
||
process { | ||
# Get the piped in object | ||
$pipedIn = $_ | ||
# If we have no name, return | ||
if (-not $name) { return } | ||
|
||
# Get the module context | ||
$moduleContext = | ||
# (if it was already piped in, we already have it) | ||
if ($pipedIn -is [Management.Automation.PSModuleInfo]) { | ||
$name = $pipedIn | ||
$pipedIn | ||
} else { | ||
Get-Module $Name | Select-Object -First 1 | ||
} | ||
|
||
# Return if there is no module context. | ||
if (-not $moduleContext) { return } | ||
|
||
# Get the use commands. | ||
$useCommands = $moduleContent.ExportedCommands[@( | ||
"Use-$($moduleContext.Name)", | ||
"Use.$($moduleContext.Name)" | ||
"$($moduleContext.Name).Use" | ||
)] | ||
|
||
# Get the use method. | ||
$useMethod = $moduleContext.psobject.methods["Use"] | ||
|
||
$ToRun = | ||
# If we have a method | ||
if ($useMethod) | ||
{ | ||
$useMethod.Script # use it | ||
# (and pass the script block as an argument) | ||
$ArgumentList = @($ScriptBlock) + @($ArgumentList) | ||
} | ||
# If we have any use commands, use the first one | ||
elseif ($useCommands -ne $null) | ||
{ | ||
@($useCommands -ne $null)[0] | ||
# (and pass the script block as an argument) | ||
$ArgumentList = @($ScriptBlock) + @($ArgumentList) | ||
} | ||
else | ||
{ | ||
# Otherwise, use the script block | ||
$ScriptBlock | ||
} | ||
|
||
# We're running in the module context, and now we know what we want `$toRun`. | ||
$runningIn = $moduleContext | ||
|
||
# The rest of the code is tedium. | ||
# If there were arguments and parameters, pass them both with splatting. | ||
if ($ArgumentList) { | ||
if ($Parameter) { | ||
. $runningIn $ToRun @ArgumentList @Parameter | ||
} else { | ||
. $runningIn $ToRun @ArgumentList | ||
} | ||
} elseif ($Parameter) { | ||
# If there were only parameters, pass them with splatting. | ||
. $runningIn $ToRun @Parameter | ||
} else { | ||
# If there were no arguments or parameters, just run the script block. | ||
. $runningIn $ToRun | ||
} | ||
} | ||
|
||
} |