Skip to content

Commit 28c4fa2

Browse files
author
James Rhoat
authored
Initial Upload
0 parents  commit 28c4fa2

10 files changed

+652
-0
lines changed

Contributing.md

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
Here, we'll help you understand how to contribute to the project, and talk about fun stuff like styles and guidelines.
2+
3+
# Contributing
4+
5+
Let's sum this up saying that we'd love your help. There are several ways to contribute:
6+
7+
- Create new commands (PowerShell knowledge required)
8+
- Report bugs (everyone can do it)
9+
- Tests (Pester knowledge required)
10+
- Documentation: functions, website, this guide, everything can be improved (everyone can)
11+
- Code review (PowerShell knowledge required)
12+
13+
## Documentation
14+
15+
Documentation is an area that is a good starting point.
16+
The documentation focus is around our comment-based help (CBH).
17+
The CBH is included with every public command (and some internal), and is the content you see using `Get-Help Function-Name`.
18+
Reviewing the content to ensure it is clear on what the command is used for, along with working examples is a key area of discussion.
19+
Whether you are first starting out with PowerShell or have been using it for years, your fresh eyes can help spot inaccuracies or areas of improvement on how we document each command.
20+
```Powershell
21+
function Get-Example {
22+
<#
23+
.SYNOPSIS
24+
A brief description of the function or script.
25+
26+
.DESCRIPTION
27+
A longer description.
28+
29+
.PARAMETER FirstParameter
30+
Description of each of the parameters.
31+
Note:
32+
To make it easier to keep the comments synchronized with changes to the parameters,
33+
the preferred location for parameter documentation comments is not here,
34+
but within the param block, directly above each parameter.
35+
36+
.PARAMETER SecondParameter
37+
Description of each of the parameters.
38+
39+
.INPUTS
40+
Description of objects that can be piped to the script.
41+
42+
.OUTPUTS
43+
Description of objects that are output by the script.
44+
45+
.EXAMPLE
46+
Example of how to run the script.
47+
48+
.LINK
49+
Links to further documentation.
50+
51+
.NOTES
52+
Detail on what the script does, if this is needed.
53+
54+
#>
55+
```
56+
More examples can be found by looking into Comment based help for powershell online or in the [Microsoft Documentation](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comment_based_help?view=powershell-6).
57+
58+
## Fix Bugs
59+
Submit Pull Requests targeting ideally just one ps1 file, with the name of the function being fixed as a title. Everyone will chime in reviewing the code and either approve the PR or request changes. The more targeted and focused the PR, the easier to merge, the fastest to go into the next release. Keep them as simple as possible to speed up the process. Helpful guide below:
60+
61+
- Fork the project, clone your fork, and configure the remotes
62+
- If you cloned the project a while ago, get teh latest changes
63+
- Create a new topic branch (off the main project branch) to contain your feature, change, or fix.
64+
```git checkout -b <topic-branch-name>```
65+
- Commit your changes in logical chunks. For any Git project, some good rules for commit messages are
66+
- the first line is commit summary, 50 characters or less,
67+
- followed by an empty line
68+
- followed by an explanation of the commit, wrapped to 72 characters.
69+
- The first line of a commit message becomes the title of a pull request on GitHub, like the subject line of an email. Including the key info in the first line will help us respond faster to your pull.
70+
- Push your topic branch up to your fork
71+
```git push origin <topic-branch-name>```
72+
73+
74+
75+
## Parameters and Variables
76+
77+
As a reference:
78+
- when we refer to [parameters](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parameters) these at the command level for accepting input; used when calling a given command like `New-ClientIISSite -WebsiteDomain ggastrocloud.com` (`WebsiteDomain` is the parameter).
79+
- A [variable](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_variables) is used within a given command to store values or objects that are used in the given command's code.
80+
81+
We chose to follow the standards below when creating parameters and variables for a function:
82+
83+
1) Any variable used in the parameter block must have first letter of each word capitalized. (e.g. `$SqlInstance`)
84+
1) Any variable used in the parameter block **is required** to be singular.
85+
1) Any variable not part of the parameter block, that is multiple words, will follow the camelCase format. (e.g. `$dbLogin`)
86+
1) Refrain from using single character variable names (e.g. `$i` or `$x`). Try to make them "readable" in the sense that if someone sees the variable name they can get a hint what it presents (e.g. `$url`, `$site`) OR e.g. `foreach ($database in $databases)` instead of `foreach ($db in $dbs)`
87+
1) When you are working with "objects", say with databases, what variable name you use should be based on what operation you are doing. As an example: in situations where you are looping over the databases for an instance, try to use a plural variable name for the collection and then single or abbreviated name in the loop for each object of that collection. e.g. `foreach ($database in $databases)`.
88+
89+
90+
91+
## Formatting and indentation
92+
93+
Consistency is key; throughout the project and accept PRs coming from anybody.
94+
When using VSCode, install the powershell extension. They have a keyboard shortcut to format files:
95+
SHIFT+ALT+F
96+
97+
98+
## Tests
99+
100+
Remember that tests are needed to make sure the code behaves properly. The ultimate goal is for any user to be able to run this modules' tests within their environment and, depending on the result, be sure everything works as expected.
101+
102+
### How to write tests
103+
104+
To save resources and be more flexible, we split tests with tags into two main categories, `UnitTests` and `IntegrationTests`. Below is a starting list of things to consider when writing your test:
105+
106+
- `UnitTests` do not require an instance to be up and running, and are easily the most flexible to be ran on every user computer. - `IntegrationTests` instead require one or more active instances, and there is a bit of setup to do in order to run them.
107+
- Every one of the `IntegrationTests` may need to create a resource (e.g. a database Or an IIS Site).
108+
- Every resource should be named with the `testEnv_` prefix. _The test should attempt to clean up after itself leaving a pristine environment._
109+
- Try to write tests thinking they may run in each and every user's test environment.
110+
111+
You'll see that every test file is named with a simple convention `Verb-Noun*.Tests.ps1`, and this is required by [Pester](https://GitHub.com/pester/Pester), which is the de-facto standard for running tests in PowerShell.
112+
113+
### Installing Pester (PSv5a and above)
114+
115+
```Powershell
116+
If ($PSVersionTable.PSVersion.Major -eq 5) {
117+
if (Get-Module -ListAvailable -Name Pester) {
118+
Write-Output "Module exists"
119+
Write-Output "Attempting to update"
120+
Update-Module Pester -Force
121+
}
122+
else {
123+
Write-Output "Module does not exist"
124+
Write-Output "Attempting to Install"
125+
Install-module Pester -Force
126+
}
127+
}
128+
```
129+
130+
#### Serialize Data For Mock data
131+
132+
```Powershell
133+
#Location to send the Serialized Data to Disk
134+
$ExportPath= "$env:APPDATA\PoshXmlSerializationData.xml"
135+
#Function you want to Serialize
136+
$data = Get-ChildItem C:\Users\
137+
#Serialize the data to disk
138+
$data | Export-Clixml $ExportPath
139+
#copy the file item to the clipboard
140+
get-content $ExportPath | clip
141+
#Place the file into a variable in the test file
142+
$MockedSerializedgetChildItem =@'
143+
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
144+
<Obj RefId="0">
145+
<TN RefId="0">
146+
<T>System.IO.DirectoryInfo</T>
147+
<T>System.IO.FileSystemInfo</T>
148+
<T>System.MarshalByRefObject</T>
149+
<T>System.Object</T>
150+
...
151+
'@
152+
#To Deserialize the data use the following:
153+
$MockedItem = [System.Management.Automation.PSSerializer]::DeserializeAsList($MockedSerializedgetChildItem)
154+
#your $mockeditem will now contain the original data Allowing you to set static variables
155+
```
156+
157+
#### Tagging Unit Tests
158+
With Pester you have the ability to tag test describe blocks `Describe -Tags ('Unit')` This allows you to run blocks of tests without needing to subdivide tests into multiple files
159+
Unfortunately, these tags are not hardcoded - for our Module we will be using the following tags
160+
- Acceptance
161+
- Unit
162+
- Integration
163+
This means that all describe blocks need to be tagged.
164+
165+
#### $TestDrive variable to output files too
166+
TestDrive is a PowerShell PSDrive for file activity limited to the scope of a single Describe or Context block in pester.
167+
Pester creates a PSDrive inside the user's temporary drive that is accessible via a named PSDrive TestDrive:. Pester will remove this drive after the test completes. You may use this drive to isolate the file operations of your test to a temporary store.
168+
More information can be found on the [Pester Wiki](https://github.com/pester/Pester/wiki/TestDrive)
169+
170+
#### Testing code coverage with Pester
171+
To run a code coverage test against your unit tests use the following command
172+
```Powershell
173+
invoke-pester .\Tests\FunctionName.tests.ps1 -codecoverage .\Private\functionname.ps1
174+
```
175+
176+
## Extensions
177+
##### Markdown editor
178+
Created in Markdown editor extion on visual studio code
179+
###### Markdown editor ShortCuts
180+
181+
Keybindings
182+
The cmd key for Windows is ctrl.
183+
184+
Shortcuts Functionality
185+
cmd-k v Created in Markdown editor extion on visual studio code Open preview to the Side
186+
ctrl-shift-v Open preview
187+
ctrl-shift-s Sync preview / Sync source
188+
shift-enter Run Code Chunk
189+
ctrl-shift-enter Run all Code Chunks
190+
cmd-= or cmd-shift-= Preview zoom in
191+
cmd-- or cmd-shift-_ Preview zoom out
192+
cmd-0 Preview reset zoom
193+
esc Toggle sidebar TOC

Invoke-PSScriptAnalysis.ps1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
$Ps1s = $(Get-ChildItem -Path $PSScriptRoot\*.ps1 -recurse -Verbose )
2+
Import-Module PSScriptAnalyzer
3+
ForEach ($Ps1 in $ps1s){
4+
Invoke-ScriptAnalyzer -Path $($ps1.Fullname)
5+
}

Invoke-UnitPester.ps1

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<#
2+
File used to run all tests
3+
#>
4+
#$module = 'Implementation'
5+
#$ModuleRoot = Split-Path -Parent $(Split-Path -Parent $MyInvocation.MyCommand.Path)
6+
$testLocation = [IO.Path]::Combine($(Split-Path -path $($myinvocation.mycommand.path)).ToString(), "Tests")
7+
#$PublicFunctions = @((get-childitem $ModuleRoot\$module\Public\).BaseName)
8+
#$PrivateFunctions = @((get-childitem $ModuleRoot\$module\Private\).BaseName)
9+
If (!(Get-module Pester)) {
10+
Import-Module Pester
11+
}
12+
Invoke-Pester $testLocation -tag 'Unit' -OutputFormat NUnitXml -OutputFile "$PSScriptRoot\NUnitXml.xml"

Module.Format.ps1xml

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<Configuration>
3+
<ViewDefinitions>
4+
<View>
5+
<Name>Default</Name>
6+
<ViewSelectedBy>
7+
<TypeName>PSStackExchange.Question</TypeName>
8+
</ViewSelectedBy>
9+
<TableControl>
10+
<TableHeaders>
11+
<TableColumnHeader>
12+
<Width>48</Width>
13+
</TableColumnHeader>
14+
<TableColumnHeader>
15+
<Width>12</Width>
16+
</TableColumnHeader>
17+
<TableColumnHeader>
18+
<Width>5</Width>
19+
</TableColumnHeader>
20+
<TableColumnHeader>
21+
<Label>Owner</Label>
22+
<Width>15</Width>
23+
</TableColumnHeader>
24+
<TableColumnHeader>
25+
<Label>Tags</Label>
26+
<Width>20</Width>
27+
</TableColumnHeader>
28+
</TableHeaders>
29+
<TableRowEntries>
30+
<TableRowEntry>
31+
<Wrap />
32+
<TableColumnItems>
33+
<TableColumnItem>
34+
<PropertyName>Title</PropertyName>
35+
</TableColumnItem>
36+
<TableColumnItem>
37+
<PropertyName>Answer_Count</PropertyName>
38+
</TableColumnItem>
39+
<TableColumnItem>
40+
<PropertyName>Score</PropertyName>
41+
</TableColumnItem>
42+
<TableColumnItem>
43+
<ScriptBlock>$_.Owner.display_name</ScriptBlock>
44+
</TableColumnItem>
45+
<TableColumnItem>
46+
<ScriptBlock>($_.Tags | Sort-Object) -Join ', '</ScriptBlock>
47+
</TableColumnItem>
48+
</TableColumnItems>
49+
</TableRowEntry>
50+
</TableRowEntries>
51+
</TableControl>
52+
</View>
53+
<View>
54+
<Name>Default</Name>
55+
<ViewSelectedBy>
56+
<TypeName>PSStackExchange.Answer</TypeName>
57+
</ViewSelectedBy>
58+
<TableControl>
59+
<TableHeaders>
60+
<TableColumnHeader>
61+
<Width>50</Width>
62+
</TableColumnHeader>
63+
<TableColumnHeader>
64+
<Label>Owner</Label>
65+
<Width>20</Width>
66+
</TableColumnHeader>
67+
<TableColumnHeader>
68+
<Width>5</Width>
69+
</TableColumnHeader>
70+
<TableColumnHeader>
71+
<Width>11</Width>
72+
</TableColumnHeader>
73+
</TableHeaders>
74+
<TableRowEntries>
75+
<TableRowEntry>
76+
<Wrap />
77+
<TableColumnItems>
78+
<TableColumnItem>
79+
<PropertyName>Share_Link</PropertyName>
80+
</TableColumnItem>
81+
<TableColumnItem>
82+
<ScriptBlock>$_.Owner.display_name</ScriptBlock>
83+
</TableColumnItem>
84+
<TableColumnItem>
85+
<PropertyName>Score</PropertyName>
86+
</TableColumnItem>
87+
<TableColumnItem>
88+
<PropertyName>Is_Accepted</PropertyName>
89+
</TableColumnItem>
90+
</TableColumnItems>
91+
</TableRowEntry>
92+
</TableRowEntries>
93+
</TableControl>
94+
</View>
95+
</ViewDefinitions>
96+
</Configuration>

PlasterManifest.xml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<plasterManifest schemaVersion="1.0"
3+
xmlns="http://www.microsoft.com/schemas/PowerShell/Plaster/v1">
4+
<metadata>
5+
<name>ModuleTemplate</name>
6+
<version>0.1.0</version>
7+
<title>ModuleTemplate</title>
8+
<description>Used to standardize module creation on the team.</description>
9+
<author>James Rhoat</author>
10+
<id>abe7d8b0-2b42-4db3-8bfc-f4a61487e29c</id>
11+
<tags></tags>
12+
</metadata>
13+
<parameters>
14+
<parameter name="ModuleName" type="text" prompt="Name of your module" default="${PLASTER_DestinationName}"/>
15+
<parameter name="ModuleDesc" type="text" prompt="Brief description on this module" default="${PLASTER_ModuleName}"/>
16+
<parameter name="FullName" type="text" prompt="Module author's' name" default="${PLASTER_PARAM_GitHubUserName}"/>
17+
<parameter name="ModuleCompanyName" type="text" prompt="Company name" default='Modernizing Medicine' />
18+
<parameter name="PowershellVersion" type="text" prompt="Minimum Powershell Version" default='3.0' />
19+
</parameters>
20+
<content>
21+
<message> Creating folder structure </message>
22+
<file source='' destination='docs\images'/>
23+
<file source='' destination='tests'/>
24+
<file source='' destination='Public'/>
25+
<file source='' destination='Private'/>
26+
<message> Deploying files </message>
27+
<templateFile source='Tests\moduleConfiguration.tests.ps1' destination='Tests\${PLASTER_PARAM_ModuleName}Configuration.tests.ps1'/>
28+
<templateFile source='Tests\Template.tests.ps1' destination='Tests\Template.tests.ps1'/>
29+
<file source='Contributing.md' destination=''/>
30+
<file source='module.psm1' destination='${PLASTER_PARAM_ModuleName}.psm1'/>
31+
<templateFile source='module.psd1' destination='${PLASTER_PARAM_ModuleName}.psd1'/>
32+
<templateFile source='Module.Format.ps1xml' destination='${PLASTER_PARAM_ModuleName}.Format.ps1xml'/>
33+
<file source='.gitignore' destination=''/>
34+
<templateFile source='readme.md' destination=''/>
35+
</content>
36+
</plasterManifest>

Readme.MD

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Installing <%= $PLASTER_PARAM_ModuleName %>
2+
3+
Run the following to install This module. To install on a server or for all users, remove the `-Scope` parameter and run in an elevated session:
4+
5+
```powershell
6+
Import-Module <%= $PLASTER_PARAM_ModuleName %> -Force -Verbose -Scope CurrentUser
7+
8+
Get-Command -Module <%= $PLASTER_PARAM_ModuleName %>
9+
```
10+
OR
11+
12+
```powershell
13+
import-Module C:\Users\<%= $PLASTER_PARAM_FullName %>\source\repos\<%= $PLASTER_PARAM_ModuleName %> -Verbose -force -Scope CurrentUser
14+
15+
Get-Command -Module <%= $PLASTER_PARAM_ModuleName %>
16+
```
17+
18+
## Module Concept
19+
20+
21+
### Current functionality
22+
23+
24+
## Usage scenarios
25+
26+
27+
## Contributing
28+
Want to contribute to the project? See the [contributing.md](Contributing.md) for a jump start.
29+
30+
### TODOs until version 1

0 commit comments

Comments
 (0)