0

I want to merge script/function having multiple dot sourced scripts into single ps1 script/function. Each script that is included may also have its own includes and so on.

=== EDIT ===

I guess you need to be painfully obvious here on SO, so let me give trivial example:

first.ps1

. $PSScriptRoot\inc\second.ps1

"first"

second.ps1

"second"

Given the existence of function Merge that accepts main script and produces merged script:

Merge first.ps1 first-merged.ps1

the final script will look as:

first-merged.ps1

"second"
"first"

This is far from trivial to do given that you can dot source in bunch of different ways, for instance in a loop.

I suppose "powershell reader" will create something like this internally so perhaps there is a way to obtain it.

2
  • 2
    So? What's keeping you? Commented May 11, 2014 at 15:25
  • 2
    And what's the question? Commented May 11, 2014 at 16:42

2 Answers 2

3

You're looking for something like the C preprocessor? That is, merge the contents without actually executing the script, right? AFAIK PowerShell doesn't delineate between dot sourcing and script execution. Dot sourcing is just another command. So you could either A) do a transitive search via regex of files that are dot sourced or if you're up for a challenge B) use the AST to help find dot sourced files e.g.:

(Get-Command .\first.ps1).ScriptBlock.Ast.EndBlock.Statements.PipelineElements  | Where InvocationOperator -eq Dot

Outputs:

CommandElements    : {$PSScriptRoot\second.ps1}
InvocationOperator : Dot
DefiningKeyword    :
DefinedKeywords    :
Redirections       : {}
Extent             : . $PSScriptRoot\second.ps1
Parent             : . $PSScriptRoot\second.ps1

And of course, you'd have to chase down all these dot sourced files to do the same to them (to achieve transitive closure). But as you mention, this can be challenging if say the path contains a variable that you don't know until runtime.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for elaborate answer. So, it could be done easily but only for specific context i.e. static dot sourcing similar to #include in C, but it is far from trivial for dynamic includes.
@majkinetor Yup, that's my take on it.
-1

You haven't specifically asked a question here, but I assume you meant to say "how do I do this". It is a very straightforward process.

For example, from Script1.ps1 (below) we can access functions in Script3.ps1 and Script4.ps1 by simply dot sourcing a single Script2.ps1 which contains these references.

Script1.ps1

.$PSScriptRoot\Script2.ps1

Get-Script3Name
Get-Script4Name

Script2.ps1

#dot source all the scripts you need access to
$PSScriptRoot\Script3.ps1
$PSScriptRoot\Script4.ps1

Script3.ps1

Function Get-Script3Name
{
    "This is Script3"
}

Script4.ps1

Function Get-Script4Name
{
    "This is Script4"
}

Results when running Script1.ps1

This is Script3
This is Script4

For more information, I also recommend reading this older post which has some very good answers provided

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.