Skip to content

Commit 302263e

Browse files
indented-automationvexx32
authored andcommitted
✨ Adds module topic support & refactor init (#251)
* Move [KoanAttribute] to C# and formats to XML file * Refactor PSM1 and moved init scripts to /Init/ subdir * Merging Get-Koan and Get-PSKoanFile * Integrating commands * Keep Modules folder * Integrating Get-PSKoan * Makes Attribute query AST only. * Updates tests * Updates help files * Makes KoanValidation tests module aware
1 parent a282370 commit 302263e

42 files changed

Lines changed: 1851 additions & 713 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

PSKoans/Classes/KoanAttribute.ps1

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Add-Type -TypeDefinition @'
2+
using System;
3+
4+
public class KoanAttribute : Attribute
5+
{
6+
public uint Position = UInt32.MaxValue;
7+
public string Module = "_powershell";
8+
}
9+
'@
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
try {
2+
Add-AssertionOperator -Name Fail -Test {
3+
param ($ActualValue, [switch] $Negate, [string] $Because)
4+
5+
# look at https://github.com/pester/Pester/blob/master/Functions/Assertions/BeTrueOrFalse.ps1
6+
# for inspiration, or here https://mathieubuisson.github.io/pester-custom-assertions/
7+
8+
if ($Negate) {
9+
return [PSCustomObject]@{
10+
Succeeded = $false
11+
FailureMessage = "Should -Not -Fail is not a valid assertion."
12+
}
13+
}
14+
15+
if (-not $Because) {
16+
$Message = "The test failed, because the script reached the Should -Fail command call."
17+
}
18+
else {
19+
$Reason = ($Because.Trim().TrimEnd('.') -replace '^because\s', '')
20+
$Message = "The test failed, because $Reason."
21+
}
22+
23+
[PSCustomObject]@{
24+
Succeeded = $false
25+
FailureMessage = $Message
26+
}
27+
}
28+
}
29+
catch { }
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Write-Verbose 'Configuring PSKoans module'
2+
Write-Verbose 'Importing data strings'
3+
$ShowMeditationPromptData = Import-PowerShellDataFile -Path "$script:ModuleRoot/Data/Show-MeditationPrompt.Data.psd1"
4+
$script:MeditationStrings = $ShowMeditationPromptData['Koans']
5+
$script:MeditationPrompts = $ShowMeditationPromptData['Prompts']
6+
Remove-Variable -Name 'ShowMeditationPromptData'
7+
8+
$script:LibraryFolder = '~/PSKoans'
9+
Write-Verbose "Koans folder set to $script:LibraryFolder"
10+
11+
if (-not (Test-Path -Path $script:LibraryFolder)) {
12+
Write-Verbose 'Koans folder does not exist; populating the folder'
13+
Update-PSKoan -Confirm:$false
14+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
$CommandName = @(
2+
'Get-Karma'
3+
'Get-PSKoan'
4+
'Reset-PSKoan'
5+
'Show-Karma'
6+
'Update-PSKoan'
7+
)
8+
9+
#region Topic completer
10+
11+
$RegisterParams = @{
12+
CommandName = $CommandName
13+
ParameterName = 'Topic'
14+
ScriptBlock = {
15+
param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)
16+
17+
$Values = (Get-PSKoan -Scope Module -IncludeModule * -SkipAttributeParsing).Topic
18+
return @($Values) -like "$WordToComplete*"
19+
}
20+
}
21+
Register-ArgumentCompleter @RegisterParams
22+
23+
#endregion
24+
25+
#region Module / IncludeModule completer
26+
27+
$RegisterParams = @{
28+
CommandName = $CommandName
29+
ParameterName = 'Module'
30+
ScriptBlock = {
31+
param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)
32+
33+
$Values = Get-Module PSKoans |
34+
Select-Object -ExpandProperty ModuleBase |
35+
Join-Path -ChildPath 'Koans/Modules' |
36+
Get-ChildItem -Directory |
37+
Select-Object -ExpandProperty Name
38+
39+
return @($Values) -like "$WordToComplete*"
40+
}
41+
}
42+
Register-ArgumentCompleter @RegisterParams
43+
44+
$RegisterParams.ParameterName = 'IncludeModule'
45+
Register-ArgumentCompleter @RegisterParams
46+
47+
#endregion

PSKoans/Koans/Modules/.gitkeep

Whitespace-only changes.

PSKoans/PSKoans.format.ps1xml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<Configuration>
3+
<ViewDefinitions>
4+
<View>
5+
<Name>PSKoans.KoanInfo</Name>
6+
<ViewSelectedBy>
7+
<TypeName>PSKoans.KoanInfo</TypeName>
8+
</ViewSelectedBy>
9+
<TableControl>
10+
<TableHeaders>
11+
<TableColumnHeader />
12+
<TableColumnHeader />
13+
<TableColumnHeader />
14+
</TableHeaders>
15+
<TableRowEntries>
16+
<TableRowEntry>
17+
<TableColumnItems>
18+
<TableColumnItem>
19+
<PropertyName>Topic</PropertyName>
20+
</TableColumnItem>
21+
<TableColumnItem>
22+
<PropertyName>Module</PropertyName>
23+
</TableColumnItem>
24+
<TableColumnItem>
25+
<PropertyName>Position</PropertyName>
26+
</TableColumnItem>
27+
</TableColumnItems>
28+
</TableRowEntry>
29+
</TableRowEntries>
30+
</TableControl>
31+
</View>
32+
<View>
33+
<Name>PSKoans.Result</Name>
34+
<ViewSelectedBy>
35+
<TypeName>PSKoans.Result</TypeName>
36+
</ViewSelectedBy>
37+
<ListControl>
38+
<ListEntries>
39+
<ListEntry>
40+
<ListItems>
41+
<ListItem>
42+
<PropertyName>Describe</PropertyName>
43+
</ListItem>
44+
<ListItem>
45+
<PropertyName>It</PropertyName>
46+
</ListItem>
47+
<ListItem>
48+
<PropertyName>Expectation</PropertyName>
49+
</ListItem>
50+
<ListItem>
51+
<PropertyName>Meditation</PropertyName>
52+
</ListItem>
53+
<ListItem>
54+
<PropertyName>KoansPassed</PropertyName>
55+
</ListItem>
56+
<ListItem>
57+
<PropertyName>TotalKoans</PropertyName>
58+
</ListItem>
59+
<ListItem>
60+
<PropertyName>CurrentTopic</PropertyName>
61+
</ListItem>
62+
</ListItems>
63+
</ListEntry>
64+
</ListEntries>
65+
</ListControl>
66+
</View>
67+
</ViewDefinitions>
68+
</Configuration>

PSKoans/PSKoans.psd1

34 Bytes
Binary file not shown.

PSKoans/PSKoans.psm1

Lines changed: 6 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,9 @@
1313
Author: Joel Sallow
1414
#>
1515

16-
#region SupportingClasses
17-
18-
class KoanAttribute : Attribute {
19-
[uint32] $Position = [uint32]::MaxValue
20-
[string] $Module = '_powershell'
21-
22-
Koan() { }
23-
}
24-
25-
class Koan : KoanAttribute {
26-
Koan() : base() { }
27-
}
16+
$script:ModuleRoot = $PSScriptRoot
2817

29-
# load classes
18+
#region SupportingClasses
3019

3120
Get-ChildItem -Path "$PSScriptRoot/Classes" | ForEach-Object {
3221
Write-Verbose "Importing classes from file: [$($_.Name)]"
@@ -44,67 +33,8 @@ Get-ChildItem -Path "$PSScriptRoot/Public", "$PSScriptRoot/Private" | ForEach-Ob
4433

4534
#endregion ImportCommands
4635

47-
#region ModuleConfiguration
48-
49-
Write-Verbose 'Configuring PSKoans module'
50-
$script:ModuleRoot = $PSScriptRoot
51-
52-
Write-Verbose 'Importing data strings'
53-
$ShowMeditationPromptData = Import-PowerShellDataFile -Path "$script:ModuleRoot/Data/Show-MeditationPrompt.Data.psd1"
54-
$script:MeditationStrings = $ShowMeditationPromptData['Koans']
55-
$script:MeditationPrompts = $ShowMeditationPromptData['Prompts']
56-
Remove-Variable -Name 'ShowMeditationPromptData'
57-
58-
$script:LibraryFolder = $Home | Join-Path -ChildPath 'PSKoans'
59-
Write-Verbose "Koans folder set to $script:LibraryFolder"
60-
61-
if (-not (Test-Path -Path $script:LibraryFolder)) {
62-
Write-Verbose 'Koans folder does not exist; populating the folder'
63-
Update-PSKoan -Confirm:$false
64-
}
65-
66-
#endregion ModuleConfiguration
67-
68-
try {
69-
Add-AssertionOperator -Name Fail -Test {
70-
param ($ActualValue, [switch] $Negate, [string] $Because)
71-
72-
# look at https://github.com/pester/Pester/blob/master/Functions/Assertions/BeTrueOrFalse.ps1
73-
# for inspiration, or here https://mathieubuisson.github.io/pester-custom-assertions/
74-
75-
if ($Negate) {
76-
return [PSCustomObject]@{
77-
Succeeded = $false
78-
FailureMessage = "Should -Not -Fail is not a valid assertion."
79-
}
80-
}
81-
82-
if (-not $Because) {
83-
$Message = "The test failed, because the script reached the Should -Fail command call."
84-
}
85-
else {
86-
$Reason = ($Because.Trim().TrimEnd('.') -replace '^because\s', '')
87-
$Message = "The test failed, because $Reason."
88-
}
89-
90-
[PSCustomObject]@{
91-
Succeeded = $false
92-
FailureMessage = $Message
93-
}
94-
}
95-
}
96-
catch { }
97-
98-
$TypeData = @{
99-
TypeName = 'PSKoans.Result'
100-
DefaultDisplayPropertySet = @(
101-
'Describe'
102-
'It'
103-
'Expectation'
104-
'Meditation'
105-
'KoansPassed'
106-
'TotalKoans'
107-
'CurrentTopic'
108-
)
36+
#region Initialization
37+
Get-ChildItem -Path "$PSScriptRoot/Init" | ForEach-Object {
38+
Write-Verbose "Initializing module: [$($_.Name)]"
39+
. $_.FullName
10940
}
110-
Update-TypeData @TypeData -Force
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
function Assert-UnblockedFile {
2+
<#
3+
.SYNOPSIS
4+
Asserts that the file is not a file is blocked.
5+
6+
.DESCRIPTION
7+
Files may be blocked when copied from Internet zones on Windows. Blocked files will have an alternate NTFS
8+
stream named Zone.Identifier.
9+
10+
This command raises a terminating error is the file at the specified path is blocked.
11+
12+
This check is skipped if the platform is not Windows or the file does not exist.
13+
14+
.PARAMETER FileInfo
15+
An instance of System.IO.FileInfo to test.
16+
17+
.INPUTS
18+
System.IO.FileInfo
19+
20+
#>
21+
22+
[CmdletBinding()]
23+
[OutputType([System.IO.FileInfo])]
24+
param(
25+
[Parameter(Mandatory, ValueFromPipeline)]
26+
[System.IO.FileInfo]
27+
$FileInfo,
28+
29+
[Switch]
30+
$PassThru
31+
)
32+
33+
process {
34+
if ($PSVersionTable.PSEdition -ne 'Desktop' -and $PSVersionTable.Platform -ne 'Win32NT') {
35+
if ($PassThru) {
36+
return $FileInfo
37+
}
38+
}
39+
40+
if (-not $FileInfo.Exists) {
41+
if ($PassThru) {
42+
return $FileInfo
43+
}
44+
}
45+
46+
if (Get-Content -Path $FileInfo.FullName -Stream Zone.Identifier -ErrorAction SilentlyContinue) {
47+
$ErrorDetails = @{
48+
ExceptionType = 'System.IO.FileLoadException'
49+
ExceptionMessage = 'Could not read the koan file "{0}". The file is blocked and may have been copied from an Internet location. Use the Unblock-File to remove the block on the file.' -f $FileInfo.FullName
50+
ErrorId = 'PSKoans.KoanFileIsBlocked'
51+
ErrorCategory = 'ReadError'
52+
TargetObject = $FileInfo
53+
}
54+
$PSCmdlet.ThrowTerminatingError( (New-PSKoanErrorRecord @ErrorDetails) )
55+
} else {
56+
if ($PassThru) {
57+
return $FileInfo
58+
}
59+
}
60+
}
61+
}

PSKoans/Private/Get-Koan.ps1

Lines changed: 0 additions & 61 deletions
This file was deleted.

0 commit comments

Comments
 (0)