Skip to content

Commit

Permalink
0.5.0-preview
Browse files Browse the repository at this point in the history
  • Loading branch information
jdhitsolutions committed Apr 26, 2021
1 parent a6a8486 commit 7d3ff07
Show file tree
Hide file tree
Showing 19 changed files with 724 additions and 171 deletions.
19 changes: 17 additions & 2 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
# ChangeLog for PSFunctionInfo

## 0.4.0
## 0.5.0-preview

+ Added an autocompleter for the `-Tag` parameter in `Get-PSFunctionInfo`. ([Issue #4](https://github.com/jdhitsolutions/PSFunctionInfo/issues/4))
+ Added a private function, `new_psfunctioninfo`, to create a new PSFunctionInfo object from the metadata block.
+ Changed `Name` parameter in `Get-PSFunctionInfo` to `FunctionName`. The parameter is positional, so it shouldn't make much difference. **This is a breaking change.**
+ Modified `Get-PSFunctionInfo` to get metadata from files. ([Issue #3](https://github.com/jdhitsolutions/PSFunctionInfo/issues/3))
+ Modified `PSFunctionInfo` class to not require Tags in the constructor.
+ Added missing online help links.
+ Added a table view called `tags` to `psfunctioninfor.format.ps1xml`.
+ Modified `psfunctioninfor.format.ps1xml` to reduce the `Alias` column to 15.
+ Added integration into the PowerShell ISE.
+ Added integration into VS Code. ([Issue #2](https://github.com/jdhitsolutions/PSFunctionInfo/issues/2))
+ Updated help documentation.
+ Updated `README.md`.

## 0.4.0-preview

+ Added `Set-PSFunctionInfoDefaults` and `Get-PSFunctionInfoDefaults` to store default values. The defaults are stored in a JSON file at `$home\psfunctioninfo-defaults.json`. If the file is found when the module is imported, it will be used to set $PSDefaultParameterValues for this module.
+ Added `Update-PSFunctionInfoDefaults` which can be used to update defaults if they are changed after the module has been loaded.
+ Added `about_PSFunctionInfo` help.
+ Minor help updates.
+ Updated `README.md`.

## 0.3.0
## 0.3.0-preview

+ Added online help links.
+ Published pre-release module to the PowerShell Gallery.
Expand Down
Binary file modified PSFunctionInfo.psd1
Binary file not shown.
159 changes: 159 additions & 0 deletions PSFunctionInfo.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,155 @@ if (Test-Path -path $defaults) {
}
}

#Add VSCode Shortcuts
if ($host.name -eq 'Visual Studio Code Host') {
$global:PSDefaultParameterValues["New-PSFunctionInfo:Path"] = {$pseditor.GetEditorContext().CurrentFile.Path}

#create an argument completer for the Name parameter
Register-ArgumentCompleter -CommandName New-PSFunctionInfo -ParameterName Name -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)

#PowerShell code to populate $wordtoComplete
$asttokens = $pseditor.GetEditorContext().CurrentFile.tokens
$namelist = @()
for ($i=0;$i -lt $asttokens.count;$i++) {
if ($asttokens[$i].text -eq 'function') {
$namelist+= $asttokens[$i+1].text
}
}
$namelist | Where-Object {$_ -like "$WordtoComplete*"} |
ForEach-Object {
# completion text,listitem text,result type,Tooltip
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
}
elseif ($host.name -eq 'Windows PowerShell ISE Host') {
#create shortcut for the ISE
$global:PSDefaultParameterValues["New-PSFunctionInfo:Path"] = {$psise.CurrentFile.fullpath}

#add a menu item
$sb = {

Function PickList {
# A WPF function picker for the PowerShell ISE
Param([string[]]$Name)

$title = "New-PSFunctionInfo"

$form = New-Object System.Windows.Window
#define what it looks like
$form.Title = $Title
$form.Height = 200
$form.Width = 300
$form.WindowStartupLocation = [System.Windows.WindowStartupLocation]::CenterScreen

$grid = New-Object System.Windows.Controls.Grid

$label = New-Object System.Windows.Controls.Label
$label.Content = "Select a function from the list and click OK."
$label.HorizontalAlignment = "left"
$label.VerticalAlignment = "top"
$grid.AddChild($label)

$combo = New-Object System.Windows.Controls.ListBox
$combo.AllowDrop = $true

$combo.Width = 160
$combo.Height = 75
$combo.HorizontalAlignment = "left"
$combo.VerticalAlignment = "top"
$combo.Margin = "15,25,0,0"

foreach ($item in $Name) {
[void]$combo.items.Add($item)
}
$combo.SelectedIndex = 0

$grid.AddChild($combo)
#initialize an array to hold all processed objects

$ok = New-Object System.windows.controls.button
$ok.Content = "_OK"
$ok.IsDefault = $True
$ok.Width = 75
$ok.Height = 25
$ok.HorizontalAlignment = "left"
$ok.Margin = "25,100,0,0"
$OK.Add_Click( {
$global:SelectedPickItem = $combo.SelectedItem
#$combo.SelectedItem | Out-Default
$form.Close()
})
$grid.AddChild($ok)

$cancel = New-Object System.Windows.Controls.Button
$cancel.Content = "_Cancel"
$cancel.Width = 75
$cancel.Height = 25
#$cancel.HorizontalAlignment = "right"
$cancel.Margin = "150,100,0,0"
$cancel.Add_Click( {
$form.Close()
})

$grid.AddChild($cancel)

$form.AddChild($grid)
[void]($form.ShowDialog())
}

if ($psise.CurrentFile.IsSaved) {
$Path = $psise.CurrentFile.FullPath

New-Variable astTokens -Force
New-Variable astErr -Force
$AST = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$astTokens, [ref]$astErr)

$file = [System.Collections.Generic.list[string[]]]::new()
Get-Content $path | ForEach-Object { $file.Add($_) }

$name = @()
for ($i = 0; $i -lt $asttokens.count; $i++) {
if ($asttokens[$i].text -eq 'function') {
$name += $asttokens[$i + 1].text
}
} #for
if ($name) {
Remove-Variable -Name SelectedPickItem -ErrorAction SilentlyContinue
picklist -name $name
#| Out-GridView -Title "Select a function" -OutputMode Single

if ($SelectedPickItem) {
New-PSFunctionInfo -Name $SelectedPickItem -path $path

$idx = $file.findIndex( { $args[0] -match "[Ff]unction(\s+)$SelectedPickItem" })
$idx++
#save and re-open the file
[void]$psISE.CurrentPowerShellTab.files.Remove($psise.CurrentFile)
[void]$psise.CurrentPowerShellTab.Files.Add($path)
$r = $psise.CurrentPowerShellTab.Files.where( { $_.fullpath -eq $path })
$r.Editor.Focus()

if ($idx -ge 0) {
$r.Editor.SetCaretPosition($idx, 1)
$r.Editor.SelectCaretLine()
$r.Editor.EnsureVisible($idx)
}
}
} #if names found
else {
[System.Windows.MessageBox]::Show("No matching functions found in $Path", "New-PSFunctionInfo", "OK", "Information")
}
} #if saved
else {
[System.Windows.MessageBox]::Show("Please save your file first:$Path and then try again.", "New-PSFunctionInfo", "OK", "Warning")
}
}

$psise.CurrentPowerShellTab.AddOnsMenu.Submenus.add("New-PSFunctionInfo", $sb, $Null)
}

#create an argument completer
Register-ArgumentCompleter -CommandName Get-PSFunctionInfo -ParameterName Name -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Expand All @@ -21,4 +170,14 @@ Register-ArgumentCompleter -CommandName Get-PSFunctionInfo -ParameterName Name -
# completion text,listitem text,result type,Tooltip
[System.Management.Automation.CompletionResult]::new($_.name, $_.name, 'ParameterValue', $_.name)
}
}

Register-ArgumentCompleter -CommandName Get-PSFunctionInfo -ParameterName Tag -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)

(Get-PSFunctionInfoTag).where({$_ -like "$wordToComplete*"}) |
ForEach-Object {
# completion text,listitem text,result type,Tooltip
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
62 changes: 55 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# PSFunctionInfo

[![PSGallery Version](https://img.shields.io/powershellgallery/v/PSFunctionInfo.png?style=plastic&logo=powershell&label=PowerShell%20Gallery)](https://www.powershellgallery.com/packages/PSFunctionInfo/) ![PSGallery Downloads](https://img.shields.io/powershellgallery/dt/PSFunctionInfo.png?style=plastic&&logo=powershell&label=Downloads)

## Synopsis

This module contains a set of PowerShell commands to add and manage metadata in stand-alone PowerShell functions.
Expand All @@ -18,7 +20,7 @@ The module should work on both Windows PowerShell and PowerShell 7.x, even cross

The purpose of this code is to provide a way to get versioning and other metadata information for functions that may not belong to a module. This is information you want to get after the function has been loaded into your PowerShell session. I have numerous stand-alone functions. These functions don't belong to a module, so there is no version or source information. However, I'd like to use that type of information for non-module files.

The code in this module isn't concerned with loading, running, or finding functions. It queries whatever is in the `Function:` PSDrive. If the PowerShell function belongs to a module, then you'll get the module version and source. Otherwise, you can use the function metadata.
The code in this module isn't concerned with loading, running, or finding functions. By default, [Get-PSFunctionInfo](docs/Get-PSFunctionInfo.md) queries whatever is in the `Function:` PSDrive. If the PowerShell function belongs to a module, then you'll get the module version and source. Otherwise, you can use the function metadata.

![Get a single function](assets/get-psfunctioninfo-1.png)

Expand All @@ -30,9 +32,28 @@ You can also get functions by tag. Use `Get-PSFunctionInfoTag` to get a list of

![Get functions by tag](assets/get-psfunctioninfo-3.png)

The PSFunctionInfo object includes a PropertySet called AuthorInfo.

```dos
PS C:\> Get-PSFunctionInfo -Tag modules | Select-Object -property AuthorInfo
Name : Test-HelpLink
Version : 0.9.0
Source : C:\scripts\update-helplinks.ps1
CompanyName : JDH IT Solutions, Inc.
Copyright : (c) JDH IT Solutions, Inc.
Description : Test if help file is missing the online link
LastUpdate : 4/23/2021 9:21:00 AM
```

Finally, you can also search .ps1 files for PSFunctionInfo metadata.

![Get function info from file](assets/get-psfunctioninfo-file.png)

## Creating PSFunctionInfo

Use the `New-PSFunctionInfo` command to insert the metadata tag into your script file.
Use the [New-PSFunctionInfo](docs/New-PSFunctionInfo.md) command to insert the metadata tag into your script file.

```powershell
New-PSFunctionInfo -Path c:\scripts\Test-ConsoleColors.ps1 -Description "show console color combinations" -Name Test-ConsoleColor -Author "Jeff Hicks" -CompanyName "JDH IT Solutions" -Copyright "2021 JDH IT Solutions, Inc." -Tags "scripting","console"
Expand Down Expand Up @@ -91,24 +112,51 @@ There are no commands to modify or remove function metadata. It is assumed that

## PSFunctionInfo Defaults

Because you might define function metadata often, and want to maintain consistency, you can define a set of default values for `New-PSFunctionInfo`. Use the command, `Set-PSFunctionInfoDefaults`:
Because you might define function metadata often, and want to maintain consistency, you can define a set of default values for `New-PSFunctionInfo`. Use the command, [Set-PSFunctionInfoDefaults](docs/Set-PSFunctionInfoDefaults):

```powershell
Set-PSFunctionInfoDefaults -Tags "stand-alone" -Copyright "(c) JDH IT Solutions, Inc." -author "Jeff Hicks" -company "JDH IT Solutions, Inc."
```

The defaults will be stored in a JSON file at `$home\psfunctioninfo-defaults.json`. When you import this module, these values will be used to define entries in `$PSDefaultParameterValues`. Or, run `Update-PSFunctionInfoDefaults` to update parameter defaults.
The defaults will be stored in a JSON file at `$home\psfunctioninfo-defaults.json`. When you import this module, these values will be used to define entries in `$PSDefaultParameterValues`. Or, run [Update-PSFunctionInfoDefaults](docs/Update-PSFunctionInfoDefaults) to update parameter defaults.

You can use [Get-PSFunctionInfoDefaults](docs/Get-PSFunctionInfoDefaults.md) to see the current values.

## Editor Integration

When you import the module into an editor, you will get additional features to make it easier to insert PSFunctionInfo metadata into your file. It is recommended that you explicitly import the module into the editor's integrated console session. You could add an `Import-Module PSFunctionInfo` command into the editor's PowerShell profile script.

You can use `Get-PSFunctionInfoDefaults` to see the current values.
### Visual Studio Code

If you have an open file, in the integrated PowerShell console, you can run `New-PSFunctionfo` and press <kbd>TAB</kbd> to tab-complete the detected functions in the current file. The file path will automatically be detected. You can enter other values such as version, or simply press <kbd>ENTER</kbd> to insert the metadata, which you can then edit.

![vscode integration](assets/psfunctioninfo-vscode.png)

This example is taking advantage of saved defaults.

### PowerShell ISE

When you import the module in the PowerShell ISE, it will add a menu shortcut.

![ISE Menu](assets/ise-psfunction-menu.png)

With a loaded file, you could run `New-PSFunctionInfo` in the console specifying the function name. The Path will be auto-detected. Or use the menu shortcut which will give you a graphical "function picker"

![function picker](assets/ise-function-picker.png)

Select a function and click OK. The metadata block will be inserted into the file. This will not work with a file that has unsaved changes. When you insert new function metadata, the file in the ISE will be closed, re-opened, and focus should jump to the function.

![ISE metadata](assets/ise-psfunctioninfo.png)

## Background

This code is a prototype for a [suggestion](https://github.com/PowerShell/PowerShell/issues/11667) I made for PowerShell 7. Early versions of this code were published as [https://gist.github.com/jdhitsolutions/65070cd51b5cfb572bc6375f67bcbc3d](https://gist.github.com/jdhitsolutions/65070cd51b5cfb572bc6375f67bcbc3d "view the Github gist")

This module was first described at <https://jdhitsolutions.com/blog/powershell/8343/a-better-way-to-manage-powershell-functions/>.

## Roadmap

+ Add VS Code integration.
+ Extract function metadata from files directly.
+ Add function metadata by file, autodetecting the function name.

Last Updated 2021-04-22 13:04:23Z
Last Updated 2021-04-26 14:06:13Z
Binary file added assets/get-psfunctioninfo-file.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/ise-function-picker.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/ise-psfunction-menu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/ise-psfunctioninfo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/psfunctioninfo-vscode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 7d3ff07

Please sign in to comment.