To start, here is our PS profile ($profile) as we left it last time:
# Variables to hold the physical location of our current project
$projectDir = "C:\Projects\MyProject"
# Updates the current project from the SVN repository
function Update-Project
{
Write-Host "Updating project $projectDir" -ForegroundColor Yellow
svn up $projectDir
}
# Commits the current project from the SVN repository
funciton Commit-Project([string] $message)
{
Write-Host "Committing $projectDir to SVN" -ForegroundColor Yellow
svn ci $projectDir -m $message
}
So let's get down to business. There are a few things right off the bat that strike me as obvious candidates for refactoring. The first is our use of "Write-Host" with a foreground color. Let's extract a function from our use.
As is good practice let's first define our comment followed by the function:
# Write the provided text to the host with ForegroundColor Yellow
function Write-Message([string] $message)
{
Write-Host $message -ForegroundColor
}
That was quick and painless. However, it's probably a good idea to make sure the local variable $message is not null or empty and handle the error accordingly:
function Write-Message([string] $message)
{
if($message.length -eq 0)
{
Write-Error "variable [message] cannot be null" -Category InvalidArgument
$error.Clear()
break
}
Write-Host $message -ForegroundColor Yellow
}
Now that is done we can refactor our existing functions to utilize our new Write-Message function.
# Updates the current project from the SVN repository
function Update-Project
{
Write-Message "Updating project $projectDir"
svn up $projectDir
}
# Commits the current project from the SVN repository
function Commit-Project([string] $message)
{
Write-Message "Committing $projectDir to SVN"
svn ci $projectDir -m $message
}
Now we can move on to the function refactoring with some substance!
Let's first take a look at our existing Update-Project function
function Update-Project
{
Write-Message "Updating project $projectDir"
svn up $projectDir
}
As you can see this function is very simple and essentially hard-coded to always update the same project. Our first order of business is to define a new project called "MyFirstProject" in a variable $myFirstProjectDir
$myFirstProjectDir = "C:\Projects\MyFirstProject"
Now we can extend Update-Project to accept a parameter $path (along with some basic error handling)
function Update-Project([string] $path)
{
if($path.length -eq 0)
{
Write-Error "variable [path] cannot be empty" -Category InvalidArgument
$error.Clear()
break
}
svn up $path
}
We now have a more generic function which accepts a path to the directory which must be updated. We can now write a strongly typed function to utilize this generic function.
# Updates MyFirstProject
function Update-MyFirstProject
{
Update-Project $myFirstProject
}
For each new project we have we must only implement a simple one-line function to utilize existing functionality... beautiful!
Now let's refactor our Commit-Project function in the same manner
function Commit-Project([string] $path, [string] $message)
{
Write-Message "Committing $projectDir to SVN"
if($path.length -eq 0)
{
Write-Error "variable [path] cannot be empty" -Category InvalidArgument
$error.Clear()
break
}
if($message.length -eq 0)
{
Write-Error "variable [message] cannot be empty" -Category InvalidArgument
$error.Clear()
break
}
svn ci $path -m $message
}
We can now add a simple one-line function to commit MyFirstProject
# Commits MyFirstProject
function Commit-MyFirstProject([string] $message)
{
Commit-Project $myFirstProjectDir $message
}
One final modification that I'd like to make is to make our global variables constants to prevent accidental modifications. Additionally, we can now remove $projectDir as it is no longer used.
Replace "$myFirstProjectDir" with:
if($myFirstProjectDir-eq $null)
{
Set-Variable -Name myFirstProjectDir -Value "C:\Projects\MyFirstProject" -Option Constant
}
One thing to note is when defining the name of your variable "-Name myFirstProjectDir" you do not include the dollar sign ($). Additionally, we check to see if the variable is null first to prevent errors. Specifically if you do not have this safeguard PS will throw an exception stating that a variable already exists by that name.
Your complete PS profile should now look like this:
# MyFirstProject directory
if($myFirstProjectDir-eq $null)
{
Set-Variable -Name myFirstProjectDir -Value "C:\Projects\MyFirstProject" -Option Constant
}
# Updates MyFirstProject
function Update-MyFirstProject
{
Update-Project $myFirstProject
}
# Commits MyFirstProject
function Commit-MyFirstProject([string] $message)
{
Commit-Project $myFirstProjectDir $message
}
# Updates the current project from the SVN repository
function Update-Project([string] $path)
{
if($path.length -eq 0)
{
Write-Error "variable [path] cannot be empty" -Category InvalidArgument
$error.Clear()
break
}
svn up $path
}
# Commits the current project from the SVN repository
function Commit-Project([string] $path, [string] $message)
{
Write-Message "Committing $projectDir to SVN"
if($path.length -eq 0)
{
Write-Error "variable [path] cannot be empty" -Category InvalidArgument
$error.Clear()
break
}
if($message.length -eq 0)
{
Write-Error "variable [message] cannot be empty" -Category InvalidArgument
$error.Clear()
break
}
svn ci $path -m $message
}
#Write the provided text to the host with ForegroundColor Yellow
function Write-Message([string] $message)
{
if($message.length -eq 0)
{
Write-Error "variable [message] cannot be null" -Category InvalidArgument
$error.Clear()
break
}
Write-Host $message -ForegroundColor Yellow
}
Rock and Roll! I hope you enjoy this knowledge and use it as a stepping stone to more useful development!