Skip to content

Commit c142946

Browse files
Merge pull request #62 from PowershellFrameworkCollective/template-update
Template update
2 parents d832ed3 + 4aee68d commit c142946

File tree

9 files changed

+118
-78
lines changed

9 files changed

+118
-78
lines changed

PSModuleDevelopment/changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
# Changelog
2+
## 2.2.?.?
3+
- Upd: Set-PSMDEncoding - use `PSFEncoding` parameter class & tabcompletion
4+
- Upd: Template PSFProject - build directly into psm1
5+
- Upd: Template PSFProject, PSFModule - automatically read version in psm1 from psd1, rather than requiring explicit maintenance.
6+
- Fix: Template PSFTest - use category exclusions
7+
28
## 2.2.5.31 (September 29th, 2018)
39
- Fix: Template PSFProject dependencies installed correctly
410

PSModuleDevelopment/functions/refactor/Set-PSMDEncoding.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
[string[]]
4141
$Path,
4242

43-
[System.Text.Encoding]
44-
$Encoding = [System.Text.Encoding]::UTF8,
43+
[PSFEncoding]
44+
$Encoding = (Get-PSFConfigValue -FullName 'psframework.text.encoding.defaultwrite' -Fallback 'utf-8'),
4545

4646
[switch]
4747
$EnableException

PSModuleDevelopment/internal/tabcompletion/assignment.ps1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@ Register-PSFTeppArgumentCompleter -Name PSMD_templatename -Command Invoke-PSMDTe
1919
Register-PSFTeppArgumentCompleter -Name PSMD_templatestore -Command Remove-PSMDTemplate -Parameter Store
2020
Register-PSFTeppArgumentCompleter -Name PSMD_templatename -Command Remove-PSMDTemplate -Parameter TemplateName
2121

22-
#endregion Templates
22+
#endregion Templates
23+
24+
#region Refactor
25+
Register-PSFTeppArgumentCompleter -Name psframework-encoding -Command Set-PSMDEncoding -Parameter Encoding
26+
#endregion Refactor

templates/PSFModule/þnameþ.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
ModuleToProcess = 'þnameþ.psm1'
44

55
# Version number of this module.
6-
ModuleVersion = '1.0.0.0'
6+
ModuleVersion = '1.0.0'
77

88
# ID used to uniquely identify this module
99
GUID = 'þ!guid!þ'

templates/PSFModule/þnameþ.psm1

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
$script:ModuleRoot = $PSScriptRoot
2-
$script:ModuleVersion = "1.0.0.0"
2+
$script:ModuleVersion = (Import-PowerShellDataFile -Path "$($script:ModuleRoot)\þnameþ.psd1").ModuleVersion
33

44
# Detect whether at some level dotsourcing was enforced
55
$script:doDotSource = Get-PSFConfigValue -FullName þnameþ.Import.DoDotSource -Fallback $false
@@ -17,7 +17,7 @@ This is important when testing for paths.
1717
$importIndividualFiles = Get-PSFConfigValue -FullName þnameþ.Import.IndividualFiles -Fallback $false
1818
if ($þnameþ_importIndividualFiles) { $importIndividualFiles = $true }
1919
if (Test-Path (Resolve-PSFPath -Path "$($script:ModuleRoot)\..\.git" -SingleItem -NewChild)) { $importIndividualFiles = $true }
20-
if (-not (Test-Path (Resolve-PSFPath "$($script:ModuleRoot)\commands.ps1" -SingleItem -NewChild))) { $importIndividualFiles = $true }
20+
if ("<was not compiled>" -eq '<was not compiled>') { $importIndividualFiles = $true }
2121

2222
function Import-ModuleFile
2323
{
@@ -49,6 +49,7 @@ function Import-ModuleFile
4949
else { $ExecutionContext.InvokeCommand.InvokeScript($false, ([scriptblock]::Create([io.file]::ReadAllText((Resolve-Path $Path)))), $null, $null) }
5050
}
5151

52+
#region Load individual files
5253
if ($importIndividualFiles)
5354
{
5455
# Execute Preimport actions
@@ -68,18 +69,12 @@ if ($importIndividualFiles)
6869

6970
# Execute Postimport actions
7071
. Import-ModuleFile -Path "$ModuleRoot\internal\scripts\postimport.ps1"
71-
}
72-
else
73-
{
74-
if (Test-Path (Resolve-PSFPath "$($script:ModuleRoot)\resourcesBefore.ps1" -SingleItem -NewChild))
75-
{
76-
. Import-ModuleFile -Path "$($script:ModuleRoot)\resourcesBefore.ps1"
77-
}
78-
79-
. Import-ModuleFile -Path "$($script:ModuleRoot)\commands.ps1"
8072

81-
if (Test-Path (Resolve-PSFPath "$($script:ModuleRoot)\resourcesAfter.ps1" -SingleItem -NewChild))
82-
{
83-
. Import-ModuleFile -Path "$($script:ModuleRoot)\resourcesAfter.ps1"
84-
}
85-
}
73+
# End it here, do not load compiled code below
74+
return
75+
}
76+
#endregion Load individual files
77+
78+
#region Load compiled code
79+
"<compile code into here>"
80+
#endregion Load compiled code

templates/PSFProject/README.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,32 @@
22

33
Insert a useful description for the þnameþ project here.
44

5-
Remember, it's the first thing a visitor will see.
5+
Remember, it's the first thing a visitor will see.
6+
7+
# Project Setup Instructions
8+
## Working with the layout
9+
10+
- Don't touch the psm1 file
11+
- Place functions you export in `functions/` (can have subfolders)
12+
- Place private/internal functions invisible to the user in `internal/functions` (can have subfolders)
13+
- Don't add code directly to the `postimport.ps1` or `preimport.ps1`.
14+
Those files are designed to import other files only.
15+
- When adding files you load during `preimport.ps1`, be sure to add corresponding entries to `filesBefore.txt`.
16+
The text files are used as reference when compiling the module during the build script.
17+
- When adding files you load during `postimport.ps1`, be sure to add corresponding entries to `filesAfter.txt`.
18+
The text files are used as reference when compiling the module during the build script.
19+
20+
## Setting up CI/CD
21+
22+
> To create a PR validation pipeline, set up tasks like this:
23+
24+
- Install Prerequisites (PowerShell Task; VSTS-Prerequisites.ps1)
25+
- Validate (PowerShell Task; VSTS-Validate.ps1)
26+
- Publish Test Results (Publish Test Results; NUnit format; Run no matter what)
27+
28+
> To create a build/publish pipeline, set up tasks like this:
29+
30+
- Install Prerequisites (PowerShell Task; VSTS-Prerequisites.ps1)
31+
- Validate (PowerShell Task; VSTS-Validate.ps1)
32+
- Build (PowerShell Task; VSTS-Build.ps1)
33+
- Publish Test Results (Publish Test Results; NUnit format; Run no matter what)

templates/PSFProject/build/vsts-build.ps1

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,21 @@ It expects as input an ApiKey authorized to publish the module.
55
Insert any build steps you may need to take before publishing it here.
66
#>
77
param (
8-
$ApiKey
8+
$ApiKey,
9+
10+
$WorkingDirectory = $env:SYSTEM_DEFAULTWORKINGDIRECTORY
911
)
1012

1113
# Prepare publish folder
1214
Write-PSFMessage -Level Important -Message "Creating and populating publishing directory"
13-
$publishDir = New-Item -Path $env:SYSTEM_DEFAULTWORKINGDIRECTORY -Name publish -ItemType Directory
14-
Copy-Item -Path "$($env:SYSTEM_DEFAULTWORKINGDIRECTORY)\þnameþ" -Destination $publishDir.FullName -Recurse -Force
15+
$publishDir = New-Item -Path $WorkingDirectory -Name publish -ItemType Directory
16+
Copy-Item -Path "$($WorkingDirectory)\þnameþ" -Destination $publishDir.FullName -Recurse -Force
1517

16-
# Create commands.ps1
18+
#region Gather text data to compile
1719
$text = @()
18-
Get-ChildItem -Path "$($publishDir.FullName)\þnameþ\internal\functions\" -Recurse -File -Filter "*.ps1" | ForEach-Object {
19-
$text += [System.IO.File]::ReadAllText($_.FullName)
20-
}
21-
Get-ChildItem -Path "$($publishDir.FullName)\þnameþ\functions\" -Recurse -File -Filter "*.ps1" | ForEach-Object {
22-
$text += [System.IO.File]::ReadAllText($_.FullName)
23-
}
24-
$text -join "`n`n" | Set-Content -Path "$($publishDir.FullName)\þnameþ\commands.ps1"
25-
26-
# Create resourcesBefore.ps1
2720
$processed = @()
28-
$text = @()
21+
22+
# Gather Stuff to run before
2923
foreach ($line in (Get-Content "$($PSScriptRoot)\filesBefore.txt" | Where-Object { $_ -notlike "#*" }))
3024
{
3125
if ([string]::IsNullOrWhiteSpace($line)) { continue }
@@ -40,11 +34,16 @@ foreach ($line in (Get-Content "$($PSScriptRoot)\filesBefore.txt" | Where-Object
4034
$processed += $item.FullName
4135
}
4236
}
43-
if ($text) { $text -join "`n`n" | Set-Content -Path "$($publishDir.FullName)\þnameþ\resourcesBefore.ps1" }
4437

45-
# Create resourcesAfter.ps1
46-
$processed = @()
47-
$text = @()
38+
# Gather commands
39+
Get-ChildItem -Path "$($publishDir.FullName)\þnameþ\internal\functions\" -Recurse -File -Filter "*.ps1" | ForEach-Object {
40+
$text += [System.IO.File]::ReadAllText($_.FullName)
41+
}
42+
Get-ChildItem -Path "$($publishDir.FullName)\þnameþ\functions\" -Recurse -File -Filter "*.ps1" | ForEach-Object {
43+
$text += [System.IO.File]::ReadAllText($_.FullName)
44+
}
45+
46+
# Gather stuff to run afterwards
4847
foreach ($line in (Get-Content "$($PSScriptRoot)\filesAfter.txt" | Where-Object { $_ -notlike "#*" }))
4948
{
5049
if ([string]::IsNullOrWhiteSpace($line)) { continue }
@@ -59,7 +58,14 @@ foreach ($line in (Get-Content "$($PSScriptRoot)\filesAfter.txt" | Where-Object
5958
$processed += $item.FullName
6059
}
6160
}
62-
if ($text) { $text -join "`n`n" | Set-Content -Path "$($publishDir.FullName)\þnameþ\resourcesAfter.ps1" }
61+
#endregion Gather text data to compile
62+
63+
#region Update the psm1 file
64+
$fileData = Get-Content -Path "$($publishDir.FullName)\þnameþ\þnameþ.psm1" -Raw
65+
$fileData = $fileData -replace '"<was not compiled>"', '"<was compiled>"'
66+
$fileData = $fileData -replace '"<compile code into here>"', ($text -join "`n`n")
67+
[System.IO.File]::WriteAllText("$($publishDir.FullName)\þnameþ\þnameþ.psm1", $fileData, [System.Text.Encoding]::UTF8)
68+
#endregion Update the psm1 file
6369

6470
# Publish to Gallery
6571
Publish-Module -Path "$($publishDir.FullName)\þnameþ" -NuGetApiKey $ApiKey -Force

templates/PSFTests/general/Manifest.Tests.ps1

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
Describe "Validating the module manifest" {
22
$moduleRoot = (Resolve-Path "$PSScriptRoot\..\..").Path
33
$manifest = ((Get-Content "$moduleRoot\þnameþ.psd1") -join "`n") | Invoke-Expression
4-
[version]$moduleVersion = Get-Item "$moduleRoot\þnameþ.psm1" | Select-String -Pattern '\$script:ModuleVersion = "(.*?)"' | ForEach-Object { $_.Matches[0].Groups[1].Value }
54
Context "Basic resources validation" {
65
$files = Get-ChildItem "$moduleRoot\functions" -Recurse -File -Filter "*.ps1"
76
It "Exports all functions in the public folder" {
@@ -18,10 +17,6 @@
1817
$files = Get-ChildItem "$moduleRoot\internal\functions" -Recurse -File -Filter "*.ps1"
1918
$files | Where-Object BaseName -In $manifest.FunctionsToExport | Should -BeNullOrEmpty
2019
}
21-
22-
It "Has the same version as the psm1 file" {
23-
([version]$manifest.ModuleVersion) | Should -Be $moduleVersion
24-
}
2520
}
2621

2722
Context "Individual file validation" {

templates/PSFTests/pester.ps1

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,50 +27,56 @@ $totalRun = 0
2727
$testresults = @()
2828

2929
#region Run General Tests
30-
Write-PSFMessage -Level Important -Message "Modules imported, proceeding with general tests"
31-
foreach ($file in (Get-ChildItem "$PSScriptRoot\general" -Filter "*.Tests.ps1"))
30+
if ($TestGeneral)
3231
{
33-
Write-PSFMessage -Level Significant -Message " Executing <c='em'>$($file.Name)</c>"
34-
þ!testresults!þ
35-
foreach ($result in $results)
32+
Write-PSFMessage -Level Important -Message "Modules imported, proceeding with general tests"
33+
foreach ($file in (Get-ChildItem "$PSScriptRoot\general" -Filter "*.Tests.ps1"))
3634
{
37-
$totalRun += $result.TotalCount
38-
$totalFailed += $result.FailedCount
39-
$result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object {
40-
$name = $_.Name
41-
$testresults += [pscustomobject]@{
42-
Describe = $_.Describe
43-
Context = $_.Context
44-
Name = "It $name"
45-
Result = $_.Result
46-
Message = $_.FailureMessage
35+
Write-PSFMessage -Level Significant -Message " Executing <c='em'>$($file.Name)</c>"
36+
þ!testresults!þ
37+
foreach ($result in $results)
38+
{
39+
$totalRun += $result.TotalCount
40+
$totalFailed += $result.FailedCount
41+
$result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object {
42+
$name = $_.Name
43+
$testresults += [pscustomobject]@{
44+
Describe = $_.Describe
45+
Context = $_.Context
46+
Name = "It $name"
47+
Result = $_.Result
48+
Message = $_.FailureMessage
49+
}
4750
}
4851
}
4952
}
5053
}
5154
#endregion Run General Tests
5255

5356
#region Test Commands
54-
Write-PSFMessage -Level Important -Message "Proceeding with individual tests"
55-
foreach ($file in (Get-ChildItem "$PSScriptRoot\functions" -Recurse -File -Filter "*Tests.ps1"))
57+
if ($TestFunctions)
5658
{
57-
if ($file.Name -notlike $Include) { continue }
58-
if ($file.Name -like $Exclude) { continue }
59-
60-
Write-PSFMessage -Level Significant -Message " Executing $($file.Name)"
61-
þ!testresults!þ
62-
foreach ($result in $results)
59+
Write-PSFMessage -Level Important -Message "Proceeding with individual tests"
60+
foreach ($file in (Get-ChildItem "$PSScriptRoot\functions" -Recurse -File -Filter "*Tests.ps1"))
6361
{
64-
$totalRun += $result.TotalCount
65-
$totalFailed += $result.FailedCount
66-
$result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object {
67-
$name = $_.Name
68-
$testresults += [pscustomobject]@{
69-
Describe = $_.Describe
70-
Context = $_.Context
71-
Name = "It $name"
72-
Result = $_.Result
73-
Message = $_.FailureMessage
62+
if ($file.Name -notlike $Include) { continue }
63+
if ($file.Name -like $Exclude) { continue }
64+
65+
Write-PSFMessage -Level Significant -Message " Executing $($file.Name)"
66+
þ!testresults!þ
67+
foreach ($result in $results)
68+
{
69+
$totalRun += $result.TotalCount
70+
$totalFailed += $result.FailedCount
71+
$result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object {
72+
$name = $_.Name
73+
$testresults += [pscustomobject]@{
74+
Describe = $_.Describe
75+
Context = $_.Context
76+
Name = "It $name"
77+
Result = $_.Result
78+
Message = $_.FailureMessage
79+
}
7480
}
7581
}
7682
}

0 commit comments

Comments
 (0)