Skip to content

Instantly share code, notes, and snippets.

@jpbruckler
Last active June 22, 2016 05:27
Show Gist options
  • Save jpbruckler/91897130b501686720798f4223fbb4b2 to your computer and use it in GitHub Desktop.
Save jpbruckler/91897130b501686720798f4223fbb4b2 to your computer and use it in GitHub Desktop.
Finds files that don't have a corresponding pester test, then creates Github issues for the missing tests
<#
.SYNOPSIS
Creates Github issues for missing Pester tests.
.DESCRIPTION
Recurses through .ps1 files and tries to find a matching .tests.ps1 file in
a given test directory. For each missing Pester test, a github issues is
created.
There are some assumptions here, namely that every .ps1 file in the $ScanPath
contains a single function. That's just how I write modules, so this script
works well for me.
.PARAMETER Owner
The repo owner. Usually your username, but could also be the group that
the repo is contained in. Basically, browse to the repo on Github.com
and look at the url.
If the URL is https://github.com/octocat/Hello-World, then owner would
be octocat.
.PARAMETER Username
If your github username is different than the owner of the repo, provide
your username via this parameter. If your username and the repo owner are
the same, you can ignore this parameter.
.PARAMETER ApiKey
Your github API key in plain text.
.PARAMETER Repo
The name of the repo where issues should be created.
.PARAMETER ScanPath
The path to the directory that this script should scan for .ps1 files from.
A recursive search for files is performed.
.PARAMETER TestsDirectoryName
The name of the directory where the Pester tests can be found. If no value
is provided, it's assumed that there is a directory named 'Tests' that is
a child folder of $ScanPath.
#>
param(
[Parameter(Mandatory)]
[string] $Owner,
[string] $Username,
[Parameter(Mandatory)]
[string] $ApiKey,
[Parameter(Mandatory)]
[string] $Repo,
[Parameter(Mandatory)]
[string] $ScanPath,
[string] $TestsDirectoryName = 'Tests'
)
function Get-FilesWithNoTests
{
<#
.SYNOPSIS
Returns file names for .ps1 files that do not have a corresponding
.tests.ps1 file.
.DESCRIPTION
For a given path, will find all .ps1 files that do not have a .tests.ps1
file in a test directory.
#>
param(
[Parameter(Mandatory)]
[string] $ScanPath,
[string] $TestsDirectoryName = 'Tests'
)
process {
if (!(Test-Path $ScanPath -ErrorAction SilentlyContinue)) {
throw ('Module path not found at: {0}' -f $ScanPath)
}
$TestsPath = (Join-Path $ScanPath $TestsDirectoryName)
if (!(Test-Path $TestsPath -ErrorAction SilentlyContinue)) {
throw ('Test directory not found at: {0}' -f $TestsPath)
}
$Files = Get-ChildItem -Path $ScanPath -Include *.ps1 -Recurse -File |
Where-Object {
$DirLeaf = Split-Path $PSItem.Directory -Leaf
$DirLeaf -notmatch 'Tests'
} | Select-Object Name
$Tests = Get-Childitem -Path $TestsPath -Recurse -Name -File
foreach ($File in $Files) {
$TestFileName = $File.Name -replace '.ps1','.tests.ps1'
if ($TestFileName -notin $Tests) {
Write-Output $File.Name
}
}
}
}
if ($null -eq $Username) { $Username = $Owner }
$BaseURI = 'https://api.github.com'
$Uri = '{0}/repos/{1}/{2}/issues' -f $BaseURI,$Owner,$Repo
$AuthToken = '{0}:{1}' -f $Username, $ApiKey
$AuthToken = [System.Convert]::ToBase64String([char[]] $AuthToken)
$Headers = @{
Authorization = 'Basic {0}' -f $AuthToken
}
$MissingTests = Get-FilesWithNoTests -ScanPath $ScanPath -TestsDirectoryName $TestsDirectoryName
try {
foreach ($MissingTest in $MissingTests) {
$Body = @{
title = 'Missing Pester test for {0}' -f ($MissingTest -replace '.ps1','')
body = 'No corresponding pester test file for file: {0}' -f $MissingTest
labels = @('pester')
}
$JSON = $Body | ConvertTo-JSON
$Response = Invoke-RestMethod -Method POST -Headers $Headers -Body $JSON -Uri $Uri
Write-Output $Response | Select-Object id,number,title
}
}
catch {
$PSItem.Exception.Message
$PSItem.ErrorDetails
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment