├── BlogPost
├── PlasterManifest.ps1
├── PlasterManifest.xml
└── blogPost.md
├── Function
├── PlasterManifest.xml
├── functionTemplate.ps1
└── testsTemplate.ps1
├── Module
├── .gitignore
├── CommandFlow.ps1
├── PlasterManifest.xml
├── README.md
├── basicTest.ps1
├── default.build.ps1
└── template.psm1
├── PlasterTemplates.psd1
├── README.md
└── Tests
└── PlasterTemplates.tests.ps1
/BlogPost/PlasterManifest.ps1:
--------------------------------------------------------------------------------
1 | PlasterManifest {
2 | Metadata {
3 | Title = "Blog Post"
4 | TemplateName = 'BlogPost'
5 | Author = "David Christian"
6 | Description = "Creates a new blog post draft for OverPoweredShell.com"
7 | TemplateVersion = '0.0.1'
8 | }
9 |
10 | Parameters {
11 | text -Name PostTitle -Prompt "Title of your new post"
12 | }
13 |
14 | Content {
15 | TemplateFile -Source 'blogPost.md' -Destination '${PLASTER_PARAM_PostTitle}.md'
16 | }
17 | } | Export-PlasterManifest -Destination .\PlasterManifest.xml -Verbose
--------------------------------------------------------------------------------
/BlogPost/PlasterManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | BlogPost
5 | c66f23d4-5e74-4606-b194-f2c5d4db9a19
6 | 0.0.1
7 | Blog Post
8 | Creates a new blog post draft for OverPoweredShell.com
9 | David Christian
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/BlogPost/blogPost.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: post
3 | <%
4 | "title: $PLASTER_PARAM_PostTitle"
5 | %>
6 | ---
7 |
8 | Write some stuff about your post here!
9 |
10 | **The Good Stuff:**
11 | Is it really good though?
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Function/PlasterManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | FunctionTemplate
6 | c0b57946d-f52f-4168-b152-4fdb334b9fca
7 | 0.0.1
8 | DC Custom Function Template
9 | Plaster template to create an advanced function with tests.
10 | David Christian
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Function/functionTemplate.ps1:
--------------------------------------------------------------------------------
1 | <%
2 | "function $PLASTER_PARAM_FunctionName"
3 | %>
4 | {
5 | <%
6 | If ($PLASTER_PARAM_Help -eq 'Yes')
7 | {
8 | @"
9 | <#
10 | .Synopsis
11 | Short description
12 | .DESCRIPTION
13 | Long description
14 | .EXAMPLE
15 | Example of how to use this cmdlet
16 | #>
17 | "@
18 | }
19 | %>
20 | <%
21 | if ($PLASTER_PARAM_CmdletBinding -eq 'Simple')
22 | {
23 | @"
24 | [CmdletBinding()]
25 | "@
26 | }
27 | else
28 | {
29 | @'
30 | [CmdletBinding(DefaultParameterSetName='Parameter Set 1',
31 | SupportsShouldProcess=$true,
32 | PositionalBinding=$false,
33 | HelpUri = 'http://www.microsoft.com/',
34 | ConfirmImpact='Medium')]
35 | '@
36 | }
37 | %>
38 | Param
39 | (
40 | <%
41 | if ($PLASTER_PARAM_ComputerName -eq 'Yes')
42 | {
43 | @'
44 | [Parameter(
45 | ValueFromPipeline=$true,
46 | ValueFromPipelineByPropertyName=$true,
47 | Position=0)]
48 | [string[]]
49 | $ComputerName
50 | '@
51 | }
52 | %>
53 | )
54 | <%
55 | if ($PLASTER_PARAM_PipelineSupport -eq 'Yes')
56 | {
57 | @'
58 | begin
59 | {
60 |
61 | }
62 | process
63 | {
64 | '@
65 | }
66 | %>
67 | <%
68 | if ($PLASTER_PARAM_ComputerName -eq 'Yes' -and $PLASTER_PARAM_PipelineSupport -eq 'Yes')
69 | {
70 | @'
71 | forEach ($computer in $ComputerName)
72 | {
73 |
74 | }
75 | '@
76 | }
77 | elseif ($PLASTER_PARAM_ComputerName -eq 'Yes')
78 | {
79 | @'
80 | forEach ($computer in $ComputerName)
81 | {
82 |
83 | }
84 | '@
85 | }
86 | %>
87 | <%
88 | if ($PLASTER_PARAM_PipelineSupport -eq 'Yes')
89 | {
90 | @'
91 | }
92 | end
93 | {
94 |
95 | }
96 | '@
97 | }
98 | %>
99 | }
--------------------------------------------------------------------------------
/Function/testsTemplate.ps1:
--------------------------------------------------------------------------------
1 | <%
2 | "Describe $PLASTER_PARAM_FunctionName {"
3 | %>
4 | It "Needs to have real tests" {
5 | $true | Should be $true
6 | }
7 | }
--------------------------------------------------------------------------------
/Module/.gitignore:
--------------------------------------------------------------------------------
1 | Output/
--------------------------------------------------------------------------------
/Module/CommandFlow.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [Parameter()]
3 | [string]
4 | $DestinationPath,
5 |
6 | [Parameter()]
7 | [switch]
8 | $HideGraph
9 | )
10 |
11 | $exportParams = @{
12 | ShowGraph = $true
13 | }
14 |
15 | if($HideGraph)
16 | {
17 | $exportParams.ShowGraph = $false
18 | }
19 |
20 | if($DestinationPath)
21 | {
22 | $exportParams.DestinationPath = $DestinationPath
23 | }
24 |
25 | graph CommandFlow {
26 | $moduleRoot = Split-Path -Path $PSScriptRoot -Parent
27 | $scripts = @{}
28 | $folders = @()
29 |
30 | if (Test-Path -Path "$moduleRoot\Public")
31 | {
32 | $folders += "$moduleRoot\Public\*ps1"
33 | }
34 |
35 | if (Test-Path -Path "$moduleRoot\Internal")
36 | {
37 | $folders += "$moduleRoot\Internal\*ps1"
38 | }
39 |
40 | Get-ChildItem -Path $folders |
41 | ForEach-Object -Process {
42 | $scripts[$PSItem.BaseName] = $PSItem.FullName
43 | }
44 |
45 | $scriptNames = $scripts.Keys | Sort-Object
46 | ForEach ($script in $scriptNames)
47 | {
48 |
49 | node $script
50 | $contents = Get-Content -Path $scripts[$script] -ErrorAction Stop
51 | $errors = $null
52 | $commands = ([System.Management.Automation.PSParser]::Tokenize($contents, [ref]$errors) |
53 | Where-Object -FilterScript {$PSItem.Type -eq 'Command'}).Content
54 | ForEach ($command in $commands)
55 | {
56 | If ($scripts[$command])
57 | {
58 | Edge $script -To $command
59 | }
60 | }
61 | }
62 | } | Export-PSGraph @exportParams
--------------------------------------------------------------------------------
/Module/PlasterManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | ModuleTemplate
6 | f7717d26-d77f-4358-8480-5928f7766bff
7 | 1.0.0
8 | DC Custom Module Template
9 | Plaster template to create a module
10 | David Christian
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | Setting up your project
48 |
49 |
50 | Creating you folders for module:
51 |
52 |
53 |
54 |
55 |
56 | Setting up support for Pester
57 |
58 |
59 |
60 | Setting up support for Git
61 |
62 |
63 | Setting up support for Invoke-Build
64 |
65 |
66 | Setting up support for PSGraph
67 |
68 |
69 |
70 | Setting up support for PlatyPS
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/Module/README.md:
--------------------------------------------------------------------------------
1 | <%
2 | "# $($PLASTER_PARAM_ModuleName)"
3 | ""
4 | "$PLASTER_PARAM_ModuleDesc"
5 | %>
--------------------------------------------------------------------------------
/Module/basicTest.ps1:
--------------------------------------------------------------------------------
1 | $moduleRoot = Resolve-Path "$PSScriptRoot\.."
2 | $moduleName = Split-Path $moduleRoot -Leaf
3 |
4 | Describe "General project validation: $moduleName" {
5 |
6 | $scripts = Get-ChildItem $moduleRoot -Include *.ps1, *.psm1, *.psd1 -Recurse
7 |
8 | # TestCases are splatted to the script so we need hashtables
9 | $testCase = $scripts | Foreach-Object {@{file = $_}}
10 | It "Script should be valid powershell" -TestCases $testCase {
11 | param($file)
12 |
13 | $file.fullname | Should Exist
14 |
15 | $contents = Get-Content -Path $file.fullname -ErrorAction Stop
16 | $errors = $null
17 | $null = [System.Management.Automation.PSParser]::Tokenize($contents, [ref]$errors)
18 | $errors.Count | Should Be 0
19 | }
20 | }
--------------------------------------------------------------------------------
/Module/default.build.ps1:
--------------------------------------------------------------------------------
1 | <%
2 | $buildParams = @("task . Clean", "Build")
3 | if ($PLASTER_PARAM_Pester -eq "Yes")
4 | {
5 | $buildParams += "Tests"
6 | }
7 |
8 | if ($PLASTER_PARAM_PlatyPS -eq "Yes")
9 | {
10 | $buildParams += "ExportHelp"
11 | }
12 |
13 | if ($PLASTER_PARAM_PSGraph -eq "Yes")
14 | {
15 | $buildParams += "GenerateGraph"
16 | }
17 |
18 | $buildParams += "Stats"
19 |
20 | $buildParams -join ", "
21 | %>
22 | <%
23 | if ($PLASTER_PARAM_Pester -eq "Yes")
24 | {
25 | "task Tests ImportCompipledModule, Pester"
26 | }
27 |
28 | %>
29 | <%
30 | $tasks = @("task CreateManifest CopyPSD, UpdatPublicFunctionsToExport")
31 | if ($PLASTER_PARAM_FunctionFolders -contains 'DSCResources')
32 | {
33 | $tasks += "UpdateDSCResourceToExport"
34 | }
35 | ($tasks -join ", ")
36 | %>
37 | task Build Compile, CreateManifest
38 | task Stats RemoveStats, WriteStats
39 |
40 | $script:ModuleName = Split-Path -Path $PSScriptRoot -Leaf
41 | $script:ModuleRoot = $PSScriptRoot
42 | $script:OutPutFolder = "$PSScriptRoot\Output"
43 | <%
44 | $folders = @()
45 | if ($PLASTER_PARAM_FunctionFolders -contains 'Public')
46 | {
47 | $folders += "'Public'"
48 | }
49 |
50 | if ($PLASTER_PARAM_FunctionFolders -contains 'Internal')
51 | {
52 | $folders += "'Internal'"
53 | }
54 |
55 | if ($PLASTER_PARAM_FunctionFolders -contains 'Classes')
56 | {
57 | $folders += "'Classes'"
58 | }
59 |
60 | if ($PLASTER_PARAM_FunctionFolders -contains 'DSCResources')
61 | {
62 | $folders += "'DSCResources'"
63 | }
64 |
65 | $importfolders = $folders -join ", "
66 |
67 | '$script:ImportFolders = @({0})' -f $importfolders
68 | %>
69 | $script:PsmPath = Join-Path -Path $PSScriptRoot -ChildPath "Output\$($script:ModuleName)\$($script:ModuleName).psm1"
70 | $script:PsdPath = Join-Path -Path $PSScriptRoot -ChildPath "Output\$($script:ModuleName)\$($script:ModuleName).psd1"
71 | <%
72 | if ($PLASTER_PARAM_PlatyPS -eq "Yes")
73 | {
74 | '$script:HelpPath = Join-Path -Path $PSScriptRoot -ChildPath "Output\$($script:ModuleName)\en-US"'
75 | }
76 | %>
77 |
78 | $script:PublicFolder = 'Public'
79 | $script:DSCResourceFolder = 'DSCResources'
80 |
81 |
82 | task "Clean" {
83 | if (-not(Test-Path $script:OutPutFolder))
84 | {
85 | New-Item -ItemType Directory -Path $script:OutPutFolder > $null
86 | }
87 |
88 | Remove-Item -Path "$($script:OutPutFolder)\*" -Force -Recurse
89 | }
90 |
91 | $compileParams = @{
92 | Inputs = {
93 | foreach ($folder in $script:ImportFolders)
94 | {
95 | Get-ChildItem -Path $folder -Recurse -File -Filter '*.ps1'
96 | }
97 | }
98 |
99 | Output = {
100 | $script:PsmPath
101 | }
102 | }
103 |
104 | task Compile @compileParams {
105 | if (Test-Path -Path $script:PsmPath)
106 | {
107 | Remove-Item -Path $script:PsmPath -Recurse -Force
108 | }
109 | New-Item -Path $script:PsmPath -Force > $null
110 |
111 | foreach ($folder in $script:ImportFolders)
112 | {
113 | $currentFolder = Join-Path -Path $script:ModuleRoot -ChildPath $folder
114 | Write-Verbose -Message "Checking folder [$currentFolder]"
115 |
116 | if (Test-Path -Path $currentFolder)
117 | {
118 | $files = Get-ChildItem -Path $currentFolder -File -Filter '*.ps1'
119 | foreach ($file in $files)
120 | {
121 | Write-Verbose -Message "Adding $($file.FullName)"
122 | Get-Content -Path $file.FullName >> $script:PsmPath
123 | }
124 | }
125 | }
126 | }
127 |
128 | task CopyPSD {
129 | New-Item -Path (Split-Path $script:PsdPath) -ItemType Directory -ErrorAction 0
130 | $copy = @{
131 | Path = "$($script:ModuleName).psd1"
132 | Destination = $script:PsdPath
133 | Force = $true
134 | Verbose = $true
135 | }
136 | Copy-Item @copy
137 | }
138 |
139 | task UpdatPublicFunctionsToExport -if (Test-Path -Path $script:PublicFolder) {
140 | $publicFunctions = (Get-ChildItem -Path $script:PublicFolder |
141 | Select-Object -ExpandProperty BaseName) -join "', '"
142 |
143 | $publicFunctions = "FunctionsToExport = @('{0}')" -f $publicFunctions
144 |
145 | (Get-Content -Path $script:PsdPath) -replace "FunctionsToExport = '\*'", $publicFunctions |
146 | Set-Content -Path $script:PsdPath
147 | }
148 |
149 | <%
150 | if ($PLASTER_PARAM_FunctionFolders -contains 'DSCResources')
151 | {
152 | @'
153 | task UpdateDSCResourceToExport -if (Test-Path -Path $script:DSCResourceFolder) {
154 | $resources = (Get-ChildItem -Path $script:DSCResourceFolder |
155 | Select-Object -ExpandProperty BaseName) -join "', '"
156 |
157 | $resources = "'{0}'" -f $resources
158 |
159 | (Get-Content -Path $script:PsdPath) -replace "'_ResourcesToExport_'", $resources |
160 | Set-Content -Path $script:PsdPath
161 | }
162 | '@
163 | }
164 | %>
165 |
166 | task ImportCompipledModule -if (Test-Path -Path $script:PsmPath) {
167 | Get-Module -Name $script:ModuleName |
168 | Remove-Module -Force
169 | Import-Module -Name $script:PsdPath -Force
170 | }
171 |
172 | <%
173 | if ($PLASTER_PARAM_Pester -eq "Yes")
174 | {
175 | @'
176 | task Pester {
177 | $resultFile = "{0}\testResults{1}.xml" -f $script:OutPutFolder, (Get-date -Format 'yyyyMMdd_hhmmss')
178 | $testFolder = Join-Path -Path $PSScriptRoot -ChildPath 'Tests\*'
179 | Invoke-Pester -Path $testFolder -OutputFile $resultFile -OutputFormat NUnitxml
180 | }
181 | '@
182 | }
183 | %>
184 |
185 | <%
186 | if ($PLASTER_PARAM_PSGraph -eq "Yes")
187 | {
188 | @'
189 | task GenerateGraph -if (Test-Path -Path 'Graphs') {
190 | $Graphs = Get-ChildItem -Path "Graphs\*"
191 |
192 | Foreach ($graph in $Graphs)
193 | {
194 | $graphLocation = [IO.Path]::Combine($script:OutPutFolder, $script:ModuleName, "$($graph.BaseName).png")
195 | . $graph.FullName -DestinationPath $graphLocation -Hide
196 | }
197 | }
198 | '@
199 | }
200 | %>
201 |
202 |
203 | task RemoveStats -if (Test-Path -Path "$($script:OutPutFolder)\stats.json") {
204 | Remove-Item -Force -Verbose -Path "$($script:OutPutFolder)\stats.json"
205 | }
206 |
207 | task WriteStats {
208 | $folders = Get-ChildItem -Directory |
209 | Where-Object {$PSItem.Name -ne 'Output'}
210 |
211 | $stats = foreach ($folder in $folders)
212 | {
213 | $files = Get-ChildItem "$($folder.FullName)\*" -File
214 | if($files)
215 | {
216 | Get-Content -Path $files |
217 | Measure-Object -Word -Line -Character |
218 | Select-Object -Property @{N = "FolderName"; E = {$folder.Name}}, Words, Lines, Characters
219 | }
220 | }
221 | $stats | ConvertTo-Json > "$script:OutPutFolder\stats.json"
222 | }
223 |
224 | <%
225 | if ($PLASTER_PARAM_PlatyPS -eq "Yes")
226 | {
227 | @'
228 | task ExportHelp -if (Test-Path -Path "$script:ModuleRoot\Help") {
229 | New-ExternalHelp -Path "$script:ModuleRoot\Help" -OutputPath $script:HelpPath
230 | }
231 | '@
232 | }
233 | %>
--------------------------------------------------------------------------------
/Module/template.psm1:
--------------------------------------------------------------------------------
1 | $functionFolders = @('Public', 'Internal', 'Classes')
2 | ForEach ($folder in $functionFolders)
3 | {
4 | $folderPath = Join-Path -Path $PSScriptRoot -ChildPath $folder
5 | If (Test-Path -Path $folderPath)
6 | {
7 | Write-Verbose -Message "Importing from $folder"
8 | $functions = Get-ChildItem -Path $folderPath -Filter '*.ps1'
9 | ForEach ($function in $functions)
10 | {
11 | Write-Verbose -Message " Importing $($function.BaseName)"
12 | . $($function.FullName)
13 | }
14 | }
15 | }
16 | $publicFunctions = (Get-ChildItem -Path "$PSScriptRoot\Public" -Filter '*.ps1').BaseName
17 | Export-ModuleMember -Function $publicFunctions
--------------------------------------------------------------------------------
/PlasterTemplates.psd1:
--------------------------------------------------------------------------------
1 | @{
2 | RootModule = 'PlasterTemplates'
3 | ModuleVersion = '0.0.1'
4 | GUID = '66a75c73-a800-473b-9bff-5942a3363a36'
5 | Author = 'David Christian'
6 | CompanyName = 'OverPoweredShell.com'
7 | Description = 'Collection of Plaster Templates Created by David Christian'
8 | PrivateData = @{
9 | PSData = @{
10 | Extensions = @{
11 | Module = 'Plaster'
12 | Details = @{
13 | TemplatePaths = @('Function', 'Module')
14 | }
15 | }
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Plaster Templates by David Christian
2 |
3 | A central repository for my Plater Templates
--------------------------------------------------------------------------------
/Tests/PlasterTemplates.tests.ps1:
--------------------------------------------------------------------------------
1 | Describe PlasterTemplates {
2 | BeforeAll {
3 | $moduleRoot = "$PSScriptRoot\.."
4 | $moduleData = Import-PowerShellDataFile -Path "$moduleRoot\PlasterTemplates.psd1"
5 | }
6 |
7 | It "Should have module data" {
8 | $moduleData | Should not be $null
9 | }
10 |
11 | It "Should have Plaster Extensions" {
12 | $moduleData.PrivateData.PSData.Extensions.Module -contains 'Plaster' | Should be $true
13 | }
14 |
15 | ForEach($templatePath in $moduleData.PrivateData.PSData.Extensions.Details.TemplatePaths)
16 | {
17 | $manifestPath = [System.IO.Path]::Combine($moduleRoot,$templatePath,"PlasterManifest.Xml")
18 |
19 | It "Should have a manifest for Path [$templatePath]" {
20 | Test-Path -Path $manifestPath | Should be $true
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------