From fb7c7b1af96bbdf4ed043e6e5906e136cf08000b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 30 Jan 2025 20:21:59 +0100 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20README?= =?UTF-8?q?=20and=20refactor=20functions=20for=20improved=20clarity=20and?= =?UTF-8?q?=20usability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 31 ++++++------------- src/finally.ps1 | 3 -- src/functions/public/Get-FunctionAlias.ps1 | 30 ++++++++++++++++++ src/functions/public/Get-FunctionName.ps1 | 17 ++++++++++ src/header.ps1 | 3 -- src/manifest.psd1 | 5 --- tests/Module.Tests.ps1 | 17 +++++++--- .../Test-Function.ps1 | 5 +-- 8 files changed, 72 insertions(+), 39 deletions(-) delete mode 100644 src/finally.ps1 create mode 100644 src/functions/public/Get-FunctionAlias.ps1 create mode 100644 src/functions/public/Get-FunctionName.ps1 delete mode 100644 src/header.ps1 delete mode 100644 src/manifest.psd1 rename src/functions/public/Test-PSModuleTemplate.ps1 => tests/Test-Function.ps1 (76%) diff --git a/README.md b/README.md index 8a69e52..db49f83 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # AST -A PowerShell module for using the Abstract Syntax Tree (AST) to analyze any PowerShell code. +A PowerShell module for using the Abstract Syntax Tree (AST) on any PowerShell code. ## Prerequisites @@ -12,29 +12,21 @@ This uses the following external resources: To install the module from the PowerShell Gallery, you can use the following command: ```powershell -Install-PSResource -Name YourModuleName -Import-Module -Name YourModuleName +Install-PSResource -Name AST +Import-Module -Name AST ``` ## Usage Here is a list of example that are typical use cases for the module. -### Example 1: Greet an entity +### Example 1: Get the function name from a script -Provide examples for typical commands that a user would like to do with the module. +This example shows how to get the function name from a script. ```powershell -Greet-Entity -Name 'World' -Hello, World! -``` - -### Example 2 - -Provide examples for typical commands that a user would like to do with the module. - -```powershell -Import-Module -Name PSModuleTemplate +Get-FunctionName -Path 'Test-Me.ps1' +Test-Me ``` ### Find more examples @@ -44,11 +36,6 @@ To find more examples of how to use the module, please refer to the [examples](e Alternatively, you can use the Get-Command -Module 'This module' to find more commands that are available in the module. To find examples of each of the commands you can use Get-Help -Examples 'CommandName'. -## Documentation - -Link to further documentation if available, or describe where in the repository users can find more detailed documentation about -the module's functions and features. - ## Contributing Coder or not, you can contribute to the project! We welcome all contributions. @@ -64,6 +51,6 @@ Please see the issues tab on this project and submit a new issue that matches yo If you do code, we'd love to have your contributions. Please read the [Contribution guidelines](CONTRIBUTING.md) for more information. You can either help by picking up an existing issue or submit a new one if you have an idea for a new feature or improvement. -## Acknowledgements +## Tools -Here is a list of people and projects that helped this project in some way. +- [lzybkr/ShowPSAst](https://github.com/lzybkr/ShowPSAst) diff --git a/src/finally.ps1 b/src/finally.ps1 deleted file mode 100644 index d8fc207..0000000 --- a/src/finally.ps1 +++ /dev/null @@ -1,3 +0,0 @@ -Write-Verbose '------------------------------' -Write-Verbose '--- THIS IS A LAST LOADER ---' -Write-Verbose '------------------------------' diff --git a/src/functions/public/Get-FunctionAlias.ps1 b/src/functions/public/Get-FunctionAlias.ps1 new file mode 100644 index 0000000..e966073 --- /dev/null +++ b/src/functions/public/Get-FunctionAlias.ps1 @@ -0,0 +1,30 @@ +function Get-FunctionAlias { + param ( + # The name of the function to retrieve aliases for + [string] $Name = '*', + + # The path to the script file to parse + [string] $Path + ) + + # Parse the script file into an AST + $ast = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$null, [ref]$null) + + # Extract function definitions + $functions = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true) + + # Process each function and extract aliases + $functions | ForEach-Object { + $funcName = $_.Name + $attributes = $_.FindAll({ $args[0] -is [System.Management.Automation.Language.AttributeAst] }, $true) + $aliasAttr = $attributes | Where-Object { $_ -is [System.Management.Automation.Language.AttributeAst] -and $_.TypeName.Name -eq 'Alias' } + + if ($aliasAttr) { + $aliases = $aliasAttr.PositionalArguments | ForEach-Object { $_.ToString().Trim('"', "'") } + [PSCustomObject]@{ + Name = $funcName + Alias = $aliases + } + } + } | Where-Object { $_.Name -like $Name } +} diff --git a/src/functions/public/Get-FunctionName.ps1 b/src/functions/public/Get-FunctionName.ps1 new file mode 100644 index 0000000..68f4960 --- /dev/null +++ b/src/functions/public/Get-FunctionName.ps1 @@ -0,0 +1,17 @@ +function Get-FunctionName { + param ( + # The path to the script file to parse + [string] $Path + ) + + # Parse the script file into an AST + $ast = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$null, [ref]$null) + + # Extract function definitions + $functions = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true) + + # Process each function and extract the name + $functions | ForEach-Object { + $_.Name + } +} diff --git a/src/header.ps1 b/src/header.ps1 deleted file mode 100644 index cc1fde9..0000000 --- a/src/header.ps1 +++ /dev/null @@ -1,3 +0,0 @@ -[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains long links.')] -[CmdletBinding()] -param() diff --git a/src/manifest.psd1 b/src/manifest.psd1 deleted file mode 100644 index ff720bd..0000000 --- a/src/manifest.psd1 +++ /dev/null @@ -1,5 +0,0 @@ -# This file always wins! -# Use this file to override any of the framework defaults and generated values. -@{ - ModuleVersion = '0.0.0' -} diff --git a/tests/Module.Tests.ps1 b/tests/Module.Tests.ps1 index 86f8dc0..bfb84c9 100644 --- a/tests/Module.Tests.ps1 +++ b/tests/Module.Tests.ps1 @@ -1,8 +1,17 @@ Describe 'Module' { - Context "Function: 'Test-PSModuleTemplate'" { - It 'Should be able to call the function' { - Test-PSModuleTemplate -Name 'World' | Should -Be 'Hello, World!' - Write-Verbose (Test-PSModuleTemplate -Name 'World' | Out-String) -Verbose + BeforeAll{ + $path = Join-Path $PSScriptRoot 'Test-Function.ps1' + } + Context "Function: 'Get-FunctionName'" { + It 'Get-FunctionName gets the function name' { + $functionName = Get-FunctionName -Path $path + $functionName | Should -Be 'Get-FunctionName' + } + } + Context "Function: 'Get-FunctionAlias'" { + It 'Get-FunctionAlias gets the function alias' { + $functionAlias = Get-FunctionAlias -Path $path + $functionAlias | Should -Be 'Test' } } } diff --git a/src/functions/public/Test-PSModuleTemplate.ps1 b/tests/Test-Function.ps1 similarity index 76% rename from src/functions/public/Test-PSModuleTemplate.ps1 rename to tests/Test-Function.ps1 index 8b67bcc..6bf3089 100644 --- a/src/functions/public/Test-PSModuleTemplate.ps1 +++ b/tests/Test-Function.ps1 @@ -1,13 +1,14 @@ -function Test-PSModuleTemplate { +function Test-Function { <# .SYNOPSIS Performs tests on a module. .EXAMPLE - Test-PSModuleTemplate -Name 'World' + Test-Function -Name 'World' "Hello, World!" #> + [Alias('Test')] [CmdletBinding()] param ( # Name of the person to greet. From 530bc55caa8a3db5e7837120bf4395a8fa6ad58f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 30 Jan 2025 20:51:58 +0100 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Enhance=20documen?= =?UTF-8?q?tation=20for=20Get-FunctionAlias=20and=20Get-FunctionName;=20ad?= =?UTF-8?q?d=20Test-Function=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/public/Get-FunctionAlias.ps1 | 25 ++++++++++++++++++++-- src/functions/public/Get-FunctionName.ps1 | 20 +++++++++++++++++ tests/Module.Tests.ps1 | 5 ++--- tests/{ => src}/Test-Function.ps1 | 0 4 files changed, 45 insertions(+), 5 deletions(-) rename tests/{ => src}/Test-Function.ps1 (100%) diff --git a/src/functions/public/Get-FunctionAlias.ps1 b/src/functions/public/Get-FunctionAlias.ps1 index e966073..a4f4b11 100644 --- a/src/functions/public/Get-FunctionAlias.ps1 +++ b/src/functions/public/Get-FunctionAlias.ps1 @@ -1,9 +1,30 @@ function Get-FunctionAlias { + <# + .SYNOPSIS + Retrieves function aliases from a PowerShell script file. + + .DESCRIPTION + Parses a specified PowerShell script file to identify function definitions and extract their associated aliases. + Returns a custom object containing function names and their corresponding aliases. + + .EXAMPLE + Get-FunctionAlias -Path "C:\Scripts\MyScript.ps1" + + Retrieves all function aliases defined in the specified script file. + + .EXAMPLE + Get-FunctionAlias -Name "Get-Data" -Path "C:\Scripts\MyScript.ps1" + + Retrieves the alias information for the function named "Get-Data" from the specified script file. + #> + [CmdletBinding()] param ( - # The name of the function to retrieve aliases for + # The name of the function to search for. Defaults to all functions ('*'). + [Parameter()] [string] $Name = '*', - # The path to the script file to parse + # The path to the PowerShell script file to be parsed. + [Parameter(Mandatory)] [string] $Path ) diff --git a/src/functions/public/Get-FunctionName.ps1 b/src/functions/public/Get-FunctionName.ps1 index 68f4960..1026fdd 100644 --- a/src/functions/public/Get-FunctionName.ps1 +++ b/src/functions/public/Get-FunctionName.ps1 @@ -1,6 +1,26 @@ function Get-FunctionName { + <# + .SYNOPSIS + Extracts function names from a specified PowerShell script. + + .DESCRIPTION + Parses the given PowerShell script file and retrieves all function names + defined within it. This function utilizes the PowerShell Abstract Syntax Tree (AST) + to analyze the script and extract function definitions. + + .EXAMPLE + Get-FunctionName -Path "C:\Scripts\MyScript.ps1" + + Retrieves all function names defined in the specified script file. + + .NOTES + Uses PowerShell's AST to analyze script structure. + #> + + [CmdletBinding()] param ( # The path to the script file to parse + [Parameter(Mandatory)] [string] $Path ) diff --git a/tests/Module.Tests.ps1 b/tests/Module.Tests.ps1 index bfb84c9..03db70c 100644 --- a/tests/Module.Tests.ps1 +++ b/tests/Module.Tests.ps1 @@ -1,15 +1,14 @@ Describe 'Module' { - BeforeAll{ - $path = Join-Path $PSScriptRoot 'Test-Function.ps1' - } Context "Function: 'Get-FunctionName'" { It 'Get-FunctionName gets the function name' { + $path = Join-Path $PSScriptRoot 'src\Test-Function.ps1' $functionName = Get-FunctionName -Path $path $functionName | Should -Be 'Get-FunctionName' } } Context "Function: 'Get-FunctionAlias'" { It 'Get-FunctionAlias gets the function alias' { + $path = Join-Path $PSScriptRoot 'src\Test-Function.ps1' $functionAlias = Get-FunctionAlias -Path $path $functionAlias | Should -Be 'Test' } diff --git a/tests/Test-Function.ps1 b/tests/src/Test-Function.ps1 similarity index 100% rename from tests/Test-Function.ps1 rename to tests/src/Test-Function.ps1 From 255b95983509e8769e56e43c6d880193e3bbf406 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 30 Jan 2025 21:00:53 +0100 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20aliases?= =?UTF-8?q?=20for=20Test-Function=20to=20include=20'TestFunc'=20and=20'Tes?= =?UTF-8?q?t-Func'=20in=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Module.Tests.ps1 | 4 +++- tests/src/Test-Function.ps1 | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/Module.Tests.ps1 b/tests/Module.Tests.ps1 index 03db70c..a91162b 100644 --- a/tests/Module.Tests.ps1 +++ b/tests/Module.Tests.ps1 @@ -10,7 +10,9 @@ It 'Get-FunctionAlias gets the function alias' { $path = Join-Path $PSScriptRoot 'src\Test-Function.ps1' $functionAlias = Get-FunctionAlias -Path $path - $functionAlias | Should -Be 'Test' + $functionAlias.Alias | Should -Contain 'Test' + $functionAlias.Alias | Should -Contain 'TestFunc' + $functionAlias.Alias | Should -Contain 'Test-Func' } } } diff --git a/tests/src/Test-Function.ps1 b/tests/src/Test-Function.ps1 index 6bf3089..c594565 100644 --- a/tests/src/Test-Function.ps1 +++ b/tests/src/Test-Function.ps1 @@ -8,7 +8,8 @@ "Hello, World!" #> - [Alias('Test')] + [Alias('Test', 'TestFunc')] + [Alias('Test-Func')] [CmdletBinding()] param ( # Name of the person to greet. From 9860b189f675575f70e714ff6e55d73ce26f6416 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 30 Jan 2025 21:06:36 +0100 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20test=20f?= =?UTF-8?q?or=20Get-FunctionName=20to=20reflect=20correct=20function=20nam?= =?UTF-8?q?e=20'Test-Function'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Module.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Module.Tests.ps1 b/tests/Module.Tests.ps1 index a91162b..d1e1c57 100644 --- a/tests/Module.Tests.ps1 +++ b/tests/Module.Tests.ps1 @@ -3,7 +3,7 @@ It 'Get-FunctionName gets the function name' { $path = Join-Path $PSScriptRoot 'src\Test-Function.ps1' $functionName = Get-FunctionName -Path $path - $functionName | Should -Be 'Get-FunctionName' + $functionName | Should -Be 'Test-Function' } } Context "Function: 'Get-FunctionAlias'" {