Skip to content

Commit fcacf93

Browse files
Merge pull request #51 from PowershellFrameworkCollective/template-update
Template update
2 parents 6113bfc + cd5e59d commit fcacf93

File tree

11 files changed

+144
-28
lines changed

11 files changed

+144
-28
lines changed

PSModuleDevelopment/changelog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Changelog
2-
## 2.2.5.29
2+
## 2.2.5.30
33
- Upd: Template integrated NUnit Test Reporting
4+
- Upd: Template support for compiled module files
45

56
## 2.2.5.28 (September 08th, 2018)
67
- Fix: Template CommandTest would throw an exception due to missing quotes on a string index

build/vsts-prerequisites.ps1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
Write-Host "Installing Pester" -ForegroundColor Cyan
22
Install-Module Pester -Force -SkipPublisherCheck
3+
Write-Host "Installing PSScriptAnalyzer" -ForegroundColor Cyan
4+
Install-Module PSScriptAnalyzer -Force -SkipPublisherCheck
35
Write-Host "Installing PSFramework" -ForegroundColor Cyan
46
Install-Module PSFramework -Force -SkipPublisherCheck

templates/PSFModule/internal/configurations/configuration.ps1

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ feel totally free to split them into multiple files.
99
<#
1010
# Example Configuration
1111
Set-PSFConfig -Module 'þnameþ' -Name 'Example.Setting' -Value 10 -Initialize -Validation 'integer' -Handler { } -Description "Example configuration setting. Your module can then use the setting using 'Get-PSFConfigValue'"
12-
#>
12+
#>
13+
14+
Set-PSFConfig -Module 'þnameþ' -Name 'Import.DoDotSource' -Value $false -Initialize -Validation 'bool' -Description "Whether the module files should be dotsourced on import. By default, the files of this module are read as string value and invoked, which is faster but worse on debugging."
15+
Set-PSFConfig -Module 'þnameþ' -Name 'Import.IndividualFiles' -Value $false -Initialize -Validation 'bool' -Description "Whether the module files should be imported individually. During the module build, all module code is compiled into few files, which are imported instead by default. Loading the compiled versions is faster, using the individual files is easier for debugging and testing out adjustments."

templates/PSFModule/readme.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# PSFModule guidance
2+
3+
This is a finished module layout optimized for implementing the PSFramework.
4+
5+
If you don't care to deal with the details, this is what you need to do to get started seeing results:
6+
7+
- Add the functions you want to publish to `/functions/`
8+
- Update the `FunctionsToExport` node in the module manifest (þnameþ.psd1). All functions you want to publish should be in a list.
9+
- Add internal helper functions the user should not see to `/internal/functions/`
10+
11+
## Path Warning
12+
13+
> If you want your module to be compatible with Linux and MacOS, keep in mind that those OS are case sensitive for paths and files.
14+
15+
`Import-ModuleFile` is preconfigured to resolve the path of the files specified, so it will reliably convert weird path notations the system can't handle.
16+
Content imported through that command thus need not mind the path separator.
17+
If you want to make sure your code too will survive OS-specific path notations, get used to using `Resolve-path` or the more powerful `Resolve-PSFPath`.

templates/PSFModule/þnameþ.psm1

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
$script:ModuleRoot = $PSScriptRoot
22
$script:ModuleVersion = "1.0.0.0"
33

4+
# Detect whether at some level dotsourcing was enforced
5+
$script:doDotSource = Get-PSFConfigValue -FullName þnameþ.Import.DoDotSource -Fallback $false
6+
if ($þnameþ_dotsourcemodule) { $script:doDotSource = $true }
7+
8+
<#
9+
Note on Resolve-Path:
10+
All paths are sent through Resolve-Path/Resolve-PSFPath in order to convert them to the correct path separator.
11+
This allows ignoring path separators throughout the import sequence, which could otherwise cause trouble depending on OS.
12+
Resolve-Path can only be used for paths that already exist, Resolve-PSFPath can accept that the last leaf my not exist.
13+
This is important when testing for paths.
14+
#>
15+
16+
# Detect whether at some level loading individual module files, rather than the compiled module was enforced
17+
$importIndividualFiles = Get-PSFConfigValue -FullName þnameþ.Import.IndividualFiles -Fallback $false
18+
if ($þnameþ_importIndividualFiles) { $importIndividualFiles = $true }
19+
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 }
21+
422
function Import-ModuleFile
523
{
624
<#
@@ -31,24 +49,37 @@ function Import-ModuleFile
3149
else { $ExecutionContext.InvokeCommand.InvokeScript($false, ([scriptblock]::Create([io.file]::ReadAllText((Resolve-Path $Path)))), $null, $null) }
3250
}
3351

34-
# Detect whether at some level dotsourcing was enforced
35-
$script:doDotSource = Get-PSFConfigValue -FullName þnameþ.Import.DoDotSource -Fallback $false
36-
if ($þnameþ_dotsourcemodule) { $script:doDotSource = $true }
37-
38-
# Execute Preimport actions
39-
. Import-ModuleFile -Path "$ModuleRoot\internal\scripts\preimport.ps1"
40-
41-
# Import all internal functions
42-
foreach ($function in (Get-ChildItem "$ModuleRoot\internal\functions" -Filter "*.ps1" -Recurse -ErrorAction Ignore))
52+
if ($importIndividualFiles)
4353
{
44-
. Import-ModuleFile -Path $function.FullName
54+
# Execute Preimport actions
55+
. Import-ModuleFile -Path "$ModuleRoot\internal\scripts\preimport.ps1"
56+
57+
# Import all internal functions
58+
foreach ($function in (Get-ChildItem "$ModuleRoot\internal\functions" -Filter "*.ps1" -Recurse -ErrorAction Ignore))
59+
{
60+
. Import-ModuleFile -Path $function.FullName
61+
}
62+
63+
# Import all public functions
64+
foreach ($function in (Get-ChildItem "$ModuleRoot\functions" -Filter "*.ps1" -Recurse -ErrorAction Ignore))
65+
{
66+
. Import-ModuleFile -Path $function.FullName
67+
}
68+
69+
# Execute Postimport actions
70+
. Import-ModuleFile -Path "$ModuleRoot\internal\scripts\postimport.ps1"
4571
}
46-
47-
# Import all public functions
48-
foreach ($function in (Get-ChildItem "$ModuleRoot\functions" -Filter "*.ps1" -Recurse -ErrorAction Ignore))
72+
else
4973
{
50-
. Import-ModuleFile -Path $function.FullName
51-
}
52-
53-
# Execute Postimport actions
54-
. Import-ModuleFile -Path "$ModuleRoot\internal\scripts\postimport.ps1"
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"
80+
81+
if (Test-Path (Resolve-PSFPath "$($script:ModuleRoot)\resourcesAfter.ps1" -SingleItem -NewChild))
82+
{
83+
. Import-ModuleFile -Path "$($script:ModuleRoot)\resourcesAfter.ps1"
84+
}
85+
}

templates/PSFProject/.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,7 @@ library/þnameþ/þnameþ/obj/*
1616
þnameþ/þnameþ.psproj
1717

1818
# ignore the TestResults
19-
TestResults/*
19+
TestResults/*
20+
21+
# ignore the publishing Directory
22+
publish/*
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# List all files that are loaded in the preimport.ps1
2+
# In the order they are loaded during preimport
3+
4+
internal\configurations\*.ps1
5+
internal\tepp\*.tepp.ps1
6+
internal\tepp\assignment.ps1
7+
internal\scripts\license.ps1
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# List all files that are loaded in the postimport.ps1
2+
# In the order they are loaded during postimport

templates/PSFProject/build/vsts-build.ps1

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,61 @@ 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,
9-
$WhatIf
8+
$ApiKey
109
)
1110

12-
if ($WhatIf) { Publish-Module -Path "$($env:SYSTEM_DEFAULTWORKINGDIRECTORY)\þnameþ" -NuGetApiKey $ApiKey -Force -WhatIf }
13-
else { Publish-Module -Path "$($env:SYSTEM_DEFAULTWORKINGDIRECTORY)\þnameþ" -NuGetApiKey $ApiKey -Force }
11+
# Prepare publish folder
12+
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+
16+
# Create commands.ps1
17+
$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
27+
$processed = @()
28+
$text = @()
29+
foreach ($line in (Get-Content "$($PSScriptRoot)\filesBefore.txt" | Where-Object { $_ -notlike "#*" }))
30+
{
31+
if ([string]::IsNullOrWhiteSpace($line)) { continue }
32+
33+
$basePath = Join-Path "$($publishDir.FullName)\þnameþ" $line
34+
foreach ($entry in (Resolve-PSFPath -Path $basePath))
35+
{
36+
$item = Get-Item $entry
37+
if ($item.PSIsContainer) { continue }
38+
if ($item.FullName -in $processed) { continue }
39+
$text += [System.IO.File]::ReadAllText($item.FullName)
40+
$processed += $item.FullName
41+
}
42+
}
43+
if ($text) { $text -join "`n`n" | Set-Content -Path "$($publishDir.FullName)\þnameþ\resourcesBefore.ps1" }
44+
45+
# Create resourcesAfter.ps1
46+
$processed = @()
47+
$text = @()
48+
foreach ($line in (Get-Content "$($PSScriptRoot)\filesAfter.txt" | Where-Object { $_ -notlike "#*" }))
49+
{
50+
if ([string]::IsNullOrWhiteSpace($line)) { continue }
51+
52+
$basePath = Join-Path "$($publishDir.FullName)\þnameþ" $line
53+
foreach ($entry in (Resolve-PSFPath -Path $basePath))
54+
{
55+
$item = Get-Item $entry
56+
if ($item.PSIsContainer) { continue }
57+
if ($item.FullName -in $processed) { continue }
58+
$text += [System.IO.File]::ReadAllText($item.FullName)
59+
$processed += $item.FullName
60+
}
61+
}
62+
if ($text) { $text -join "`n`n" | Set-Content -Path "$($publishDir.FullName)\þnameþ\resourcesAfter.ps1" }
63+
64+
# Publish to Gallery
65+
Publish-Module -Path "$($publishDir.FullName)\þnameþ" -NuGetApiKey $ApiKey -Force

templates/PSFTests/general/FileIntegrity.Tests.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function Get-FileEncoding
2828
elseif ($byte[0] -eq 0xfe -and $byte[1] -eq 0xff) { 'Unicode' }
2929
elseif ($byte[0] -eq 0 -and $byte[1] -eq 0 -and $byte[2] -eq 0xfe -and $byte[3] -eq 0xff) { 'UTF32' }
3030
elseif ($byte[0] -eq 0x2b -and $byte[1] -eq 0x2f -and $byte[2] -eq 0x76) { 'UTF7' }
31-
else { 'Unknown, possible ASCII' }
31+
else { 'Unknown' }
3232
}
3333

3434
Describe "Verifying integrity of module files" {

0 commit comments

Comments
 (0)