UPDATE: The feed changed a little bit from the first time I published the format

I made changes to the twitter feed format to match the game for the FIRST FRC 2010 Season.  You can follow the tweets for this season at http://twitter.com/Frcfms 

The new format is as follows:

#FRCABC - where ABC is the Event Code. Each event has a unique code.
TY X - where x is P for Practice Q for qualification E for Elimination
MC X - where X is the match number
RF XXX - where XXX is the Red Final Score
BF XXX - where XXX is the Blue Final Score
RE XXXX YYYY ZZZZ - where XXXX is red team 1 number, YYYY is red team 2 number, ZZZZ is red team 3 number
BL XXXX YYYY ZZZZ - where XXXX is blue team 1 number, YYYY is blue team 2 number, ZZZZ is blue team 3 number
RB X - where X is the Bonus the Referee gave to Red
BB X - where X is the Bonus the Referee gave to Blue
RP X - where X are the Penalties the Referee gave to Red
BP X - where X are the Penalties the Referee gave to Blue
RG X - where X is the Goals scored by Red
BG X - where X is the Goals scored by Blue
RGP X - where X is the Goal Penalties by Red
BGP X - where X is the Goal Penalties by Blue

Example tweet in text:

#FRCTEST TY Q MC 2 RF 5 BF 3 RE 3224 2119 547 BL 587 2420 342 RB 1 BB 1 RP 0 BP 0 RG 0 BG 5 RGP 2 BGP 1

I sure would like to know if anyone builds anything that parses these tweets.

Doing agile development means deploying your application very frequently into many environments.  You might have several environments that all have different configuration settings.  Changing these settings by hand results in time consuming mistakes.  I have built a couple different console deployment tools over the years that handled this.  Usually you would run the console tool with a command line argument that would specify the environment that you wanted to configure and this tool would look up all the settings in a property file and make the changes in the app.config or web.config file.  I thought it would be fun to do something similar using powershell.

So what do I want this script to do? 

  • Keep environment specific settings in a property file
  • Support having 1 to N property files (i.e. Dev, Test, Build etc) for a project that is accepted as a parameter into the script
  • The web.config or app.config file is modified with the values that come from the property file
  • Support changing connection strings and application settings in version 1 of this script

The first steps in creating this script is to have a set of functions that can easily be used to set the entries in a config file.  I would use this script in all my projects that needed to have the ability to set connection and application settings.  This library of useful functions will be called Xml-Config.ps1

function Set-ConnectionString([string]$fileName, [string]$outFileName, [string]$name, [string]$value)
{

    # Load the config file up in memory
    [xml]$a = get-content $fileName;

    # Find the connection string to change
    $a.configuration.connectionstrings.selectsinglenode("add[@name='" + $name + "']")
       .connectionString = $value

    # Write it out to the new file
    Format-XML $a | out-file $outFileName
}
function Set-ConnectionString
([string]$fileName, [string]$outFileName, [string]$name, [string]$value)
{

    # Load the config file up in memory
    [xml]$a = get-content $fileName;

    # Find the cennection string to change
    $a.configuration.connectionstrings.selectsinglenode("add[@name='" + $name + "']")
             .connectionString = $value

    # Write it out to the new file
    Format-XML $a | out-file $outFileName
}
function Set-ApplicationSetting 
([string]$fileName, [string]$outFileName, [string]$name, [string]$value)
{

    # Load the config file up in memory
    [xml]$a = get-content $fileName;

    # Find the app settings item to change
    $a.configuration.appSettings.selectsinglenode("add[@key='" + $name + "']").value = $value

    # Write it out to the new file
    Format-XML $a | out-file $outFileName
}
function Format-XML ([xml]$xml, $indent=2) 
{ 
    $StringWriter = New-Object System.IO.StringWriter 
    $XmlWriter = New-Object System.XMl.XmlTextWriter $StringWriter 
    $xmlWriter.Formatting = "indented" 
    $xmlWriter.Indentation = $Indent 
    $xml.WriteContentTo($XmlWriter) 
    $XmlWriter.Flush() 
    $StringWriter.Flush() 
    Write-Output $StringWriter.ToString() 
}

Next I needed a script file that was specific to the software project.  I wouldn’t be re-using this script from project to project as it has very specific details that only apply to one project.  For example a software project might have a web.config for the web application but an app.config for a windows service.  It would be the job of this second script to know where these configs are located and tie the property values to the functions above.  In the following example the web.config has two settings that I want to change at deployment time (connection string and application setting).  These settings will be different for Test, Build and Development environments.  This script will be called dev.ps1.

dev.ps1

param([string]$propertyFile)

$workDir = Get-Location
. $workDir\Xml-Config.ps1
. $workDir\$propertyFile.ps1

# Change the connection string
Set-ConnectionString "web.config" "FMS_DB" $connectionString

# Change the app setting for the path to the backups
Set-ApplicationSetting "web.config" "DatabaseBackupRoot" $backupPath

Next I needed to create the property files that represented each environment. The following property file was called Test.ps1.

[string]$connectionString = "Data Source=(local); Database=FMS_TST; Integrated Security=true;"
[string]$backupPath = "c:\data\test"

So now the dev.ps1 script can be called passing in the environment that is being deployed.  In the following example the Test environment is being deployed. 

./dev.ps1 -propertyFile Test

Conclusion

I have shown you a simple way to use powershell to easily configure your application by using property files.  This technique can also be used in the automated build process to set the configuration before running integration tests.  I plan on expanding on this technique and exposing functions to set other frequently used configuration settings (logging details, WCF Endpoints, Other XML configurations).  Powershell is very powerful and makes automating complex tasks easier with less code.  In my command line console applications that performed the same function it would take a lot more lines of code to achieve the same results. 

In this post you will find my PowerPoint and source code I used for my presentation at Charlotte Alt.Net May meeting.  I had a good time presenting this to the group even though it was very broad and shallow.  I covered the basis on why you want to leverage tools and practices in a Lean Agile environment.  I got into topics like Source Control, Unit Testing, Mocking, Continuous Integration and Automated UI Testing.  Each of these topics could have been an entire 1 hour presentation on its own. 

Here are the links to the tools that I talked about in the presentation:

Power Point “Tools for Agile Development: A Developer’s Perspective” http://www.protosystem.net/downloads/ToolsForAgileCharlotteAlt.Net/ToolsForAgile.ppt

NerdDinner solution with MSTests re-written as NUnit Tests and WatiN Automated UI Tests http://www.protosystem.net/downloads/ToolsForAgileCharlotteAlt.Net/NerdDinner_ToolsForAgileDev.zip

CI Factory modified solution that I used for creating a CI Build from scratch http://www.protosystem.net/downloads/ToolsForAgileCharlotteAlt.Net/CIFactory_ToolsForAgileDev.zip