Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions PSModuleDevelopment/PSModuleDevelopment.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

# Version number of this module.

ModuleVersion = '2.2.11.139'
ModuleVersion = '2.2.11.146'

# ID used to uniquely identify this module
GUID = '37dd5fce-e7b5-4d57-ac37-832055ce49d6'
Expand All @@ -28,8 +28,8 @@
# Modules that must be imported into the global environment prior to importing
# this module
RequiredModules = @(
@{ ModuleName = 'PSFramework'; ModuleVersion = '1.6.214' }
@{ ModuleName = 'string'; ModuleVersion = '1.0.0' }
@{ ModuleName = 'PSFramework'; ModuleVersion = '1.7.270' }
@{ ModuleName = 'string'; ModuleVersion = '1.1.3' }
)

# Assemblies that must be loaded prior to importing this module
Expand Down
10 changes: 10 additions & 0 deletions PSModuleDevelopment/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## 2.2.11.146 (2023-05-31)

+ Upd: Export-PSMDString - added support for Get-PSMDLocalizedString calls (#181, thanks @nyanhp)
+ Upd: Invoke-PSMDTemplate - added support from template configuration files (#161)
+ Upd: Template MiniModule - added gitignore & main branch for automation (#179, Thanks @nyanhp)
+ Upd: Template MiniModule - switched github automation from windows-2019 to windows-latest
+ Upd: Template PSFProject - added main branch to build autopmation
+ Upd: Template PSFProject - switched github automation from windows-2019 to windows-latest
+ Upd: Templating - added common picture formats to the list of binary file extensions (#175)

## 2.2.11.139 (2022-04-29)

+ Fix: Invoke-PSMDTemplate - fails to generate templates on PS 5.1, due to splatting vs. explicitly bound parameter (#172)
Expand Down
8 changes: 4 additions & 4 deletions PSModuleDevelopment/functions/refactor/Export-PSMDString.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,17 @@
#region Command Parameters
$commandAsts = $ast.FindAll({
if ($args[0] -isnot [System.Management.Automation.Language.CommandAst]) { return $false }
if ($args[0].CommandElements[0].Value -notmatch '^Invoke-PSFProtectedCommand$|^Write-PSFMessage$|^Stop-PSFFunction$|^Test-PSFShouldProcess$') { return $false }
if (-not ($args[0].CommandElements.ParameterName -match '^String$|^ActionString$')) { return $false }
if ($args[0].CommandElements[0].Value -notmatch '^Invoke-PSFProtectedCommand$|^Write-PSFMessage$|^Stop-PSFFunction$|^Test-PSFShouldProcess$|^Get-PSFLocalizedString$') { return $false }
if (-not ($args[0].CommandElements.ParameterName -match '^String$|^ActionString$|^Name$')) { return $false }
$true
}, $true)

foreach ($commandAst in $commandAsts)
{
$stringParam = $commandAst.CommandElements | Where-Object ParameterName -match '^String$|^ActionString$'
$stringParam = $commandAst.CommandElements | Where-Object ParameterName -match '^String$|^ActionString$|^Name$'
$stringParamValue = $commandAst.CommandElements[($commandAst.CommandElements.IndexOf($stringParam) + 1)].Value

$stringValueParam = $commandAst.CommandElements | Where-Object ParameterName -match '^StringValues$|^ActionStringValues$'
$stringValueParam = $commandAst.CommandElements | Where-Object ParameterName -match '^StringValues$|^ActionStringValues$|^Name$'
if ($stringValueParam)
{
$stringValueParamValue = $commandAst.CommandElements[($commandAst.CommandElements.IndexOf($stringValueParam) + 1)].Extent.Text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@
- Will only process the parameter 'Foo'
- And replace the current text with the one specified
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]

[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
[CmdletBinding()]
Param (
Expand Down
20 changes: 12 additions & 8 deletions PSModuleDevelopment/functions/templating/Invoke-PSMDTemplate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@

.PARAMETER Silent
This places the function in unattended mode, causing it to error on anything requiring direct user input.

.PARAMETER NoConfigFile
By default, this command will look in the execution path and above for files named "PSMDConfig.psd1" to populate template parameters from.

.PARAMETER EnableException
Replaces user friendly yellow warnings with bloody red exceptions of doom!
Expand Down Expand Up @@ -132,12 +135,17 @@

[switch]
$Silent,

[switch]
$NoConfigFile,

[switch]
$EnableException
)

begin {
$resolvedPath = Resolve-PSFPath -Path $OutPath

$templates = @()
switch ($PSCmdlet.ParameterSetName) {
'NameStore' { $templates = Get-PSMDTemplate -TemplateName $TemplateName -Store $Store }
Expand All @@ -152,12 +160,8 @@
if (-not $Parameters) { $Parameters = @{ } }
if ($Name) { $Parameters["Name"] = $Name }

foreach ($config in (Get-PSFConfig -Module 'PSModuleDevelopment' -Name 'Template.ParameterDefault.*')) {
$cfgName = $config.Name -replace '^.+\.([^\.]+)$', '$1'
if (-not $Parameters.ContainsKey($cfgName)) {
$Parameters[$cfgName] = $config.Value
}
}
if ($NoConfigFile) { $paramCloned = Resolve-TemplateParameter -Configuration $Parameters -FromConfiguration}
else { $paramCloned = Resolve-TemplateParameter -Path $resolvedPath -Configuration $Parameters -FromConfiguration }
#endregion Parameter Processing

#region Helper function
Expand Down Expand Up @@ -440,8 +444,8 @@
if (Test-PSFFunctionInterrupt) { return }

$invokeParam = @{
Parameters = $Parameters.Clone()
OutPath = Resolve-PSFPath -Path $OutPath
Parameters = $paramCloned
OutPath = $resolvedPath
NoFolder = $NoFolder
Encoding = $Encoding
Raw = $Raw
Expand Down
2 changes: 1 addition & 1 deletion PSModuleDevelopment/internal/configurations/template.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Set-PSFConfig -Module 'PSModuleDevelopment' -Name 'Template.ParameterDefault.Aut
Set-PSFConfig -Module 'PSModuleDevelopment' -Name 'Template.ParameterDefault.Company' -Value "MyCompany" -Initialize -Validation 'string' -Description "The default value to set for the parameter 'Company'. This same setting can be created for any other parameter name."

# The file extensions that will not be scanned for content replacement and will be stored as bytes
Set-PSFConfig -Module 'PSModuleDevelopment' -Name 'Template.BinaryExtensions' -Value @('.dll', '.exe', '.pdf', '.doc', '.docx', '.xls', '.xlsx') -Initialize -Description "When creating a template, files with these extensions will be included as raw bytes and not interpreted for parameter insertion."
Set-PSFConfig -Module 'PSModuleDevelopment' -Name 'Template.BinaryExtensions' -Value @('.dll', '.exe', '.pdf', '.doc', '.docx', '.xls', '.xlsx','.png','.ico','.bmp','.jpg','.jpeg','.pdb') -Initialize -Description "When creating a template, files with these extensions will be included as raw bytes and not interpreted for parameter insertion."

# Define the default store. To add more stores, just add a similar setting with a different last name segment
Set-PSFConfig -Module 'PSModuleDevelopment' -Name 'Template.Store.Default' -Value (Join-Path -Path (Get-PSFPath -Name AppData) -ChildPath "WindowsPowerShell/PSModuleDevelopment/Templates") -Initialize -Validation "string" -Description "Path to the default directory where PSModuleDevelopment will store its templates. You can add additional stores by creating the same setting again, only changing the last name segment to a new name and configuring a separate path."
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
function Resolve-TemplateParameter {
<#
.SYNOPSIS
Resolves the parameters to invoke a template with.

.DESCRIPTION
Resolves the parameters to invoke a template with.

This processes parameters with the following, ascending priority:

- From Configuration (if specified)
- From PSMD Configuration files (if specified)
- From being explicitly specified on invocation

Explicitly bound parameters will thus always win.

.PARAMETER Path
Path in which the template is being invoked.
If this parameter is specified, it will search the path and all parent paths for PSMDConfig.psd1 files.
Then read the settings from them, starting at the root path.
The deeper the path, the later the settings are loaded, overwriting settings from parent folders in case of conflict.

.PARAMETER Configuration
The Configuration settings specified by the user.
These take precedence over anything else.

.PARAMETER FromConfiguration
Whether to load configuration settings from configuration.

.EXAMPLE
PS C:\> Resolve-TemplateParameter -Path $resolvedPath -Configuration $Configuration -FromConfiguration

Resolves all parameters for the current template.
#>
[OutputType([hashtable])]
[CmdletBinding()]
param (
[string]
$Path,

[hashtable]
$Configuration = @{ },

[switch]
$FromConfiguration
)
process {
$newConfiguration = @{ }

if ($Path) {
$currentPath = $Path
$paths = while ($currentPath) {
$currentPath
$currentPath = Split-Path $currentPath
}

foreach ($rootPath in $paths | Sort-Object Length) {
$configPath = Join-Path $rootPath 'PSMDConfig.psd1'
if (-not (Test-Path -Path $configPath)) { continue }

$cfg = Import-PSFPowerShellDataFile -Path $configPath
if ($cfg -and $cfg -is [hashtable]) {
foreach ($pair in $cfg.GetEnumerator()) {
$newConfiguration[$pair.Key] = $pair.Value
}
}
}
}

foreach ($pair in $Configuration.GetEnumerator()) {
$newConfiguration[$pair.Key] = $pair.Value
}

if ($FromConfiguration) {
foreach ($config in Get-PSFConfig -Module 'PSModuleDevelopment' -Name 'Template.ParameterDefault.*') {
$cfgName = $config.Name -replace '^.+\.([^\.]+)$', '$1'
if (-not $newConfiguration.ContainsKey($cfgName)) {
$newConfiguration[$cfgName] = $config.Value
}
}
}

$newConfiguration
}
}
79 changes: 61 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,70 @@
# Purpose
# PSModuleDevelopment

The PSModuleDevelopment module is designed to provide tools that help with - big surprise incoming - module development.
This attempts to help with:
- Speeding up iterative procedures, especially reinitiating tests runs
- Debugging Execution
- Development Research & Analytics
- Miscellaneous other things
Welcome to your one stop for PowerShell development tools!
This project is designed to help you with accelerating your coding workflows through a wide range of utilities.
Its flagship feature is a *templating engine* that allows you to swiftly create new projects - either by using some of the default templates or easily creating your own.

# Alias Warning
## Online Documentation

This module actually ships with convenience aliases.
As this module is part of the PSFramework project, its documentation can be found on [PSFramework.org](https://psframework.org/documentation/documents/psmoduledevelopment/templates.html).

Generally, modules should leave aliases like that to the user's preference.
However, in this instance, the main purpose is to optimize the performance of the developer, which requires the use of aliases.
> As ever, documentation takes time out of _"more features!"_, so there could be more, but at least the templating is covered in depth.

Due to this, the decision was made to ship the module with aliases.
## Install

# Configuration Notice
To get read to use this module, run this:

This module uses the PSFramework for configuration management (and many other things).
Run `Get-PSFConfig -Module PSModuleDevelopment` in order to retrieve the full list of configurations set.
```powershell
Install-Module PSModuleDevelopment -Scope CurrentUser
```

# Profile notice
## Profit

Some features of this module assume, that it is in the profile and automtically imported on console start.
It is still possible to profit from the module without this, but it is highly recommended to add the module import to the PowerShell profile
With that you are ready to go and have fun with it.
A few examples of what it can do for you:

> Create a new module project

```powershell
Invoke-PSMDTemplate MiniModule
```

> Parse a script file and export all functions into dedicated files

```powershell
Split-PSMDScriptFile -File .\largescript.ps1 -Path .\functions
```

> Fix all the file encodings

```powershell
Get-ChildItem -Recurse -File | Set-PSMDEncoding
```

> Fix parameter blocks

```powershell
Get-ChildItem -Recurse -File | Set-PSMDCmdletBinding
```

> Get better members

```powershell
Get-Date | Get-PSMDMember -Name ToString
```

> Search for Assemblies and Types

```powershell
# List all assemblies
Get-PSMDAssembly

# Search for types in that assembly
Get-PSMDAssembly *ActiveDirectory* | Find-PSMDType

# Search for all types implementing IEnumerable
Find-PSMDType -Implements IEnumerable

# Get Constructors
[DateTime] | Get-PSMDConstructor
```
5 changes: 5 additions & 0 deletions templates/DscClassBasedResource/PSMDInvoke.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
param (
$Path
)

New-PSMDTemplate -ReferencePath "$PSScriptRoot" -OutPath $Path
17 changes: 17 additions & 0 deletions templates/DscClassBasedResource/PSMDTemplate.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@{
TemplateName = 'dscclass'
Version = "1.0.0.0"
AutoIncrementVersion = $true
Tags = 'dscresource'
Author = 'Jan-Hendrik Peters'
Description = 'Basic class-based DSC resource template with support for Azure Guest Configuration'
Exclusions = @("PSMDInvoke.ps1") # Contains list of files - relative path to root - to ignore when building the template
Scripts = @{
guid = {
[System.Guid]::NewGuid().ToString()
}
year = {
Get-Date -Format "yyyy"
}
}
}
Loading