Skip to content

Commit 97feeba

Browse files
committed
Initial commit
0 parents  commit 97feeba

23 files changed

Lines changed: 1563 additions & 0 deletions

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.github/FUNDING.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# These are supported funding model platforms
2+
3+
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4+
patreon: # Replace with a single Patreon username
5+
open_collective: # Replace with a single Open Collective username
6+
ko_fi: # Replace with a single Ko-fi username
7+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9+
liberapay: # Replace with a single Liberapay username
10+
issuehunt: # Replace with a single IssueHunt username
11+
otechie: # Replace with a single Otechie username
12+
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

.github/workflows/build.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
on:
2+
push:
3+
branches:
4+
- master
5+
- main
6+
7+
jobs:
8+
build:
9+
10+
runs-on: windows-latest
11+
12+
steps:
13+
- uses: actions/checkout@v1
14+
- name: Install Prerequisites
15+
run: .\build\vsts-prerequisites.ps1
16+
shell: powershell
17+
- name: Validate
18+
run: .\build\vsts-validate.ps1
19+
shell: powershell
20+
- name: Build
21+
run: .\build\vsts-build.ps1 -ApiKey $env:APIKEY
22+
shell: powershell
23+
env:
24+
APIKEY: ${{ secrets.ApiKey }}

.github/workflows/validate.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
on: [pull_request]
2+
3+
jobs:
4+
validate:
5+
6+
runs-on: windows-latest
7+
8+
steps:
9+
- uses: actions/checkout@v1
10+
- name: Install Prerequisites
11+
run: .\build\vsts-prerequisites.ps1
12+
shell: powershell
13+
- name: Validate
14+
run: .\build\vsts-validate.ps1
15+
shell: powershell

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
publish
2+
TestResults

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Josh Dearing
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

ModuleExplorer/ModuleExplorer.psd1

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#
2+
# Module manifest for module 'ModuleExplorer'
3+
#
4+
# Generated by: Josh Dearing
5+
#
6+
# Generated on: 5/17/2025
7+
#
8+
9+
@{
10+
11+
# Script module or binary module file associated with this manifest.
12+
RootModule = 'ModuleExplorer.psm1'
13+
14+
# Version number of this module.
15+
ModuleVersion = '0.1.0'
16+
17+
# Supported PSEditions
18+
CompatiblePSEditions = 'Core'
19+
20+
# ID used to uniquely identify this module
21+
GUID = '244270ce-191e-4f04-adff-e8677a893280'
22+
23+
# Author of this module
24+
Author = 'Josh Dearing'
25+
26+
# Company or vendor of this module
27+
CompanyName = ' '
28+
29+
# Copyright statement for this module
30+
Copyright = '(c) Joshua Dearing. All rights reserved.'
31+
32+
# Description of the functionality provided by this module
33+
Description = 'A TUI for interactively exploring installed PowerShell modules and their commands.'
34+
35+
# Minimum version of the PowerShell engine required by this module
36+
PowerShellVersion = '7.4'
37+
38+
# Modules that must be imported into the global environment prior to importing this module
39+
RequiredModules = @(
40+
@{ ModuleName = 'PwshSpectreConsole'; ModuleVersion = '2.3.0' }
41+
)
42+
43+
# Assemblies that must be loaded prior to importing this module
44+
# RequiredAssemblies = @()
45+
46+
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
47+
# ScriptsToProcess = @()
48+
49+
# Type files (.ps1xml) to be loaded when importing this module
50+
# TypesToProcess = @()
51+
52+
# Format files (.ps1xml) to be loaded when importing this module
53+
# FormatsToProcess = @()
54+
55+
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
56+
# NestedModules = @()
57+
58+
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
59+
FunctionsToExport = @(
60+
'Show-ModuleExplorer'
61+
)
62+
63+
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
64+
CmdletsToExport = @()
65+
66+
# Variables to export from this module
67+
VariablesToExport = '*'
68+
69+
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
70+
AliasesToExport = @()
71+
72+
# DSC resources to export from this module
73+
# DscResourcesToExport = @()
74+
75+
# List of all modules packaged with this module
76+
# ModuleList = @()
77+
78+
# List of all files packaged with this module
79+
# FileList = @()
80+
81+
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
82+
PrivateData = @{
83+
84+
PSData = @{
85+
86+
# Tags applied to this module. These help with module discovery in online galleries.
87+
# Tags = @()
88+
89+
# A URL to the license for this module.
90+
LicenseUri = 'https://github.com/dearingdev/ModuleExplorer/blob/main/LICENSE'
91+
92+
# A URL to the main website for this project.
93+
ProjectUri = 'https://github.com/dearingdev/ModuleExplorer'
94+
95+
# A URL to an icon representing this module.
96+
# IconUri = ''
97+
98+
# ReleaseNotes of this module
99+
# ReleaseNotes = ''
100+
101+
# Prerelease string of this module
102+
# Prerelease = ''
103+
104+
# Flag to indicate whether the module requires explicit user acceptance for install/update/save
105+
# RequireLicenseAcceptance = $false
106+
107+
# External dependent modules of this module
108+
# ExternalModuleDependencies = @()
109+
110+
} # End of PSData hashtable
111+
112+
} # End of PrivateData hashtable
113+
114+
# HelpInfo URI of this module
115+
# HelpInfoURI = ''
116+
117+
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
118+
# DefaultCommandPrefix = ''
119+
120+
}
121+

ModuleExplorer/ModuleExplorer.psm1

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#Requires -Modules @{ ModuleName = 'pwshspectreconsole'; ModuleVersion = '0.7.0' }
2+
3+
foreach ($file in Get-ChildItem -Path "$PSScriptRoot/internal/functions" -Filter *.ps1 -Recurse) {
4+
. $file.FullName
5+
}
6+
7+
foreach ($file in Get-ChildItem -Path "$PSScriptRoot/functions" -Filter *.ps1 -Recurse) {
8+
. $file.FullName
9+
}
10+
11+
foreach ($file in Get-ChildItem -Path "$PSScriptRoot/internal/scripts" -Filter *.ps1 -Recurse) {
12+
. $file.FullName
13+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<#
2+
.SYNOPSIS
3+
Interactively explores available PowerShell modules and their commands.
4+
5+
.DESCRIPTION
6+
The Show-ModuleExplorer cmdlet provides an interactive, terminal-based user interface
7+
to browse through PowerShell modules installed or available on the system.
8+
Users can select a module from the list to view its commands using the Show-ModuleCommandViewer function.
9+
10+
The interface displays "Module Explorer" as a title and lists all available modules.
11+
You can filter the list of modules by providing a search string to the -Filter parameter.
12+
The list also includes options to "Refresh List" and "<-- Exit" the explorer.
13+
14+
This function utilizes PwshSpectreConsole cmdlets for a rich interactive experience.
15+
16+
.PARAMETER Filter
17+
An optional string used to filter the list of displayed modules.
18+
The function will search for modules whose names contain the filter string.
19+
Wildcards are automatically added around the provided filter string (e.g., if you provide "Util", it searches for "*Util*").
20+
21+
Type: String
22+
Position: Named
23+
Default value: None
24+
Accept pipeline input: False
25+
Accept wildcard characters: True
26+
27+
.EXAMPLE
28+
PS C:\> Show-ModuleExplorer
29+
30+
Description:
31+
Launches the Module Explorer, displaying all available PowerShell modules.
32+
You can then navigate and select a module to view its commands.
33+
34+
.EXAMPLE
35+
PS C:\> Show-ModuleExplorer -Filter "BurntToast"
36+
37+
Description:
38+
Launches the Module Explorer and filters the initial list to show only modules
39+
named "BurnToast".
40+
41+
.NOTES
42+
This function depends on several cmdlets from a PowerShell module providing Spectre.Console integration
43+
(e.g., Write-SpectreFigletText, Read-SpectreSelection, Write-SpectreHost, Write-SpectreRule, Read-SpectrePause, Get-SpectreEscapedText)
44+
for its user interface. Ensure this module and its dependencies are installed and available.
45+
46+
Upon selecting a module, this function calls `Show-ModuleCommandViewer` to display
47+
the commands within that module.
48+
49+
The explorer allows for refreshing the module list to reflect any changes (installs/uninstalls)
50+
made while the explorer is running.
51+
52+
Navigation within the selection list is done using arrow keys and Enter.
53+
The selection prompt also supports typing to filter the choices in real-time.
54+
55+
.INPUTS
56+
None
57+
This function does not accept input from the pipeline.
58+
59+
.OUTPUTS
60+
None
61+
This function does not return any objects to the pipeline. It provides an interactive display in the console.
62+
63+
.LINK
64+
None
65+
#>
66+
function Show-ModuleExplorer {
67+
[CmdletBinding()]
68+
param(
69+
[string]$Filter # Optional filter for module names
70+
)
71+
72+
try {
73+
$moduleLookup = @{} # Initialize hashtable to map display names to module objects
74+
75+
while ($true) {
76+
Clear-Host
77+
Write-SpectreFigletText -Text "Module Explorer" -Alignment "Center"
78+
$moduleQuery = @{ ListAvailable = $true }
79+
if ($Filter) {
80+
$moduleQuery.Name = $Filter
81+
}
82+
$availableModules = Get-Module @moduleQuery | Select-Object Name, Version, Path, ModuleBase, RootModule | Sort-Object Name
83+
84+
if (-not $availableModules) {
85+
Write-SpectreHost "[bold red]No PowerShell modules found.[/]"
86+
Read-SpectrePause -Message "[grey]Press Enter to continue...[/]" -NoNewline
87+
return
88+
}
89+
90+
$exitChoiceString = "[cyan]<-- Exit[/]"
91+
$refreshChoiceString = "[cyan]Refresh List[/]"
92+
# Reset the main loop if modules changes (install/remove)
93+
$moduleLookup.Clear()
94+
$moduleChoices = @($exitChoiceString, $refreshChoiceString)
95+
96+
$moduleChoices += $availableModules | ForEach-Object {
97+
$versionString = if ($_.Version) { "v$($_.Version)" } else { "Version N/A" }
98+
$displayName = "$($_.Name) ($versionString)"
99+
$moduleLookup[$displayName] = $_ # Populate the lookup table
100+
$displayName
101+
}
102+
103+
$promptTitle = "[yellow bold]Select a PowerShell Module to Explore (or Exit):[/]"
104+
Write-SpectreRule -Title "[grey] Installed Modules: $($availableModules.Count) [/]" -Alignment Center
105+
$selectedModuleDisplay = Read-SpectreSelection -Message $promptTitle -PageSize 15 -Choices $moduleChoices -EnableSearch
106+
107+
if (-not $selectedModuleDisplay -or $selectedModuleDisplay -eq $exitChoiceString) {
108+
Write-SpectreHost "[yellow]Exiting Module Explorer.[/]"
109+
break
110+
}
111+
112+
if ($selectedModuleDisplay -eq $refreshChoiceString) {
113+
Write-SpectreHost "[italic green]Refreshing module list...[/]"
114+
continue
115+
}
116+
117+
# Use the lookup table
118+
$selectedModuleObject = $moduleLookup[$selectedModuleDisplay]
119+
120+
if (-not $selectedModuleObject) {
121+
# This condition should not be met if $selectedModuleDisplay is from $moduleChoices
122+
Write-SpectreHost "[bold red]Error: Could not retrieve details for selected module: '$($selectedModuleDisplay | Get-SpectreEscapedText)'. This is unexpected.[/]"
123+
Read-SpectrePause -Message "[grey]Press Enter to continue...[/]" -NoNewline
124+
continue
125+
}
126+
127+
Clear-Host
128+
Show-ModuleCommandViewer -SelectedModule $selectedModuleObject
129+
130+
} # End of main loop
131+
}
132+
catch {
133+
Write-SpectreHost "[bold red]An unexpected error occurred in Module Explorer: $($_.Exception.ToString() | Get-SpectreEscapedText)[/]"
134+
Read-SpectrePause -Message "[grey]Press Enter to acknowledge error and exit...[/]" -NoNewline
135+
}
136+
finally {
137+
Clear-Host
138+
Write-SpectreHost "[cyan]Module Explorer session ended.[/]"
139+
}
140+
}

0 commit comments

Comments
 (0)