Archive

I’m a proud psake user and love the flexibility of PowerShell during my build process. I recently had a project that I really wanted the build number to show up in TeamCity rather than the standard incrementing number.

On my local machine, I have a spiffy “gav”–getassemblyversion–command that uses Reflection to grab the assembly version. Unfortunately, since I don’t want to rely on the local version of .NET and I’ve already set the build number in AssemblyInfo.cs as part of my build process, I just want to fetch what’s in that file.

Regular expressions to the rescue!

Here’s the final psake task. I call it as part of my build/release tasks and it generates the right meta output that TeamCity needs for the build version. Here’s a gist of the source: http://gist.github.com/440646.

For the past few projects, I’ve used BluePrintCSS and really liked the experience. It forced me both to conquer my CSS layout fears (tables no more) and standardize a few of my formatting techniques that we use on our internal and external applications. Good deal all around.

The one caveat that I really… really didn’t like was how I had to name things.

Without the BluePrintCSS guide or the CSS files available, you couldn’t look at the classes and tell much of what was going on… and it wasn’t descriptive like ‘header’ and ‘title’.

Welcome To .less (dotless)

I stumbled onto .less (aka dotless, dotlesscss, that shizzle css thingy) back in November and thought “hey, that’s cool… that’s how CSS should work” and didn’t give it much more thought. Shortly after fav’ing it in github, I noticed they pushed an update targeting BluePrintCSS operability. Cool–I’ve GOT to try this out.

Getting Started with .less

The instructions on the home page (right side of the screen) is all you need. Clone, compile, update web.config and start go!

1. Order matters. Referencing a style before you’ve ‘created’ it will bork the interperter. So @imports always go at the top and if you’re referencing within the same .less file, keep things in order.

2. Pre-compiling is fun. For now, I’m pre-compiling my .less files without using the handler and simply sending the css file up to our web server. This is easily taken care of with either a MS Build task or psake task. Here’s how an example of a quick MS Build task that references the dotless.Compiler in the solution’s “tools” directory.

3. .less files need to be ‘Content’. Since VS2008 is stupid, .less files (like .spark views, etc) need to be explicitly set to have a Build Action of ‘Content’ so that the publishing process sends them up to the web server. If you’re publishing via psake or another automation tool, then ignore this. 😉

Being an avid git user outside the workplace, I’m used to setting up .gitignore files for my ReSharper and pre-generated sludge that find their way into my projects. However, until today, I never found a clean way of handling pre-generated files with Visual SourceSafe.

Seems the answer was just in a menu that I never used (imagine that…).

Situation

For now, rather than having dotless generate my files on the fly, I’m using the compiler to compile my .less into .css files. Since I’m using the built-in publishing features (which, I am replacing with psake tasks–more on that later) for this project, any files not included in the project are skipped/not copied. That’s a bummer for my generated .css file.

The answer is to include the file in the project; however, when checked in, dotless.Compiler crashes because it can’t rewrite the file (since it’s read-only).

Solution

Exclude the file from source control. Sure, that sounds good, but how using SourceSafe?

1. Select the file, site.css in this case.

2. File > Source Control > Exclude ‘site.css’ from Source Control.

Yeah, seriously that easy. Instead of the normal lock/checkmark, a red (-) appears by the file (which is fine) and everything compiles as expected.

I’ve used SourceSafe for years now and never saw that in there… it doesn’t look like I can wildcard files or extensions like .gitignore (or even folders–the option disappears if anything but a single file is selected), but for a one-off case like this, it works just fine.

I’ve been working the last bit to find the best way to create/populate select (option) lists using a mixture of ASP.NET MVC and jQuery. What I’ve run into is that the “key” and “value” tags are not passed along when using Json(data).

Here’s what I’m trying to pull off in jQuery: building a simple select drop down list.

I’ve been tetering back and forth with PSake and my trusty NAnt scripts for quite a while now. For those not familiar with PSake, it’s build automation that makes you drunk—but in a good way. 😉 You can read James Kovacs’ original post here or check out the repository here for the latest bits.

I originally looked at rake scripts (after exposure working with Fluent NHibernate) as PowerShell is loathed in our organization—or was. That mindset is slowly changing (being able to show people how to crank out what was originally scoped at a week in two lines of PowerShell script helps out); so I’m using PSake as further motivation.

My prior PSake scripts were a bit tame. Launch msbuild, copy a few files. With the latest release of xUnit 1.5 hitting the wires over the weekend (and a much needed x86 version for my poor, cranky Oracle libraries), I decided to bite the bullet and dig in to PSake.

I had two goals:

Build a reliable framework “default.ps1” file that I could drop into almost any project and configure with little or no effort.

Compile, test, and rollout updates from a single PSake command task.

I borrowed the basic layout from Ayende’s Rhino Mocks PSake; however, I couldn’t get msbuild to run correctly simply by calling it.

Here’s what I ended up with for our internal core library. The core library, isn’t so much a “utilities” container, but just as it sounds—the framework all of our applications are built on to keep connections to our various applications (HR, student systems, data warehouses, etc) consistant as well as hold our base FNH conventions.

Properties

The properties area holds all of the configuration for the PSake script. For me, it’s common to configure $solution_name, $libraries_to_merge, and $libraries_to_copy. With our naming standards, the $test_library should be left unchanged. I also added in the tester information so we could change from XUnit to MBUnit (if Hell froze over or something)).

properties {

# ****************CONFIGURE ****************

$solution_name = “Framework”

$test_library = “$solution_name.Test.dll”

$libraries_to_merge = “antlr3.runtime.dll”, `

“ajaxcontroltoolkit.dll”, `

“Castle.DynamicProxy2.dll”, `

“Castle.Core.dll”, `

“FluentNHibernate.dll”, `

“log4net.dll”, `

“system.linq.dynamic.dll”, `

“xunit.dll”, `

“nhibernate.caches.syscache2.dll”, `

“cssfriendly.dll”, `

“iesi.collections.dll”, `

“nhibernate.bytecode.castle.dll”, `

“oracle.dataaccess.dll”

$libraries_to_copy = “system.data.sqlite.dll”

$tester_directory = “j:\shared_libraries\xunit\msbuild”

$tester_executable =“xunit.console.x86.exe”

$tools_directory = “$tools”

$base_directory= resolve-path .

$thirdparty_directory = “$base_directory\thirdparty”

$build_directory = “$base_directory\build”

$solution_file = “$base_directory\$solution_name.sln”

$release_directory = “$base_directory\release”

}

Clean and easy enough. You’ll notice that $libraries_to_merge and $libraries_to_copy are implied string arrays. That works out well since string arrays end up as params when passed to commands… and our $libraries_to_copy can be iterated over later in the code.

Compile is a bit tricky. As noted in the code, I ended up using a SharePoint example from PoSH code to get MSBuild to behave. The standard exec methodology provided by PSake kept ignoring my parameters. Maybe someone has an good reason.. but this works.

You also see that my OutDir has TWO slashes. It seems that directories with spaces require the second. I’m sure this will somehow bite me later on, but it seems to be working for now. 😉

Tasks – Test

task Test -depends Compile {

$origin_directory = pwd

cd $build_directory

exec .\$tester_executable “$build_directory\$test_library”

cd $origin_directory

}

I want to thank Ayende for the idea to dump the origin directory into a parameter—brilliant. This one is pretty simple—just calls the tester and tests.

Merge calls ILMerge and wraps all of my libraries into one. Do I need to do this? Nah, but for the framework, I prefer to keep everything together. I don’t want to be chasing mis-versioned libraries around. Again, since $libraries_to_merge is a string array, it passes each “string” as a separate parameter—which is exactly what ILMerge wants to see.

I also have ILMerge generate and keep a log of what it did—just to have. Since the build directory gets blown away between builds (and isn’t replicated to source control), then no harm. Space is mostly free. 😉

Build provides just that—building with no testing and no copying to the release directory. This is more for testing out the scripts, but useful in some cases.

Release copies the library and the xml documentation out ot the release directory. It then iterates through the string array of “other” libraries (non-manged code libraries that can’t be merged, etc) and copies them as well.

After a discussion on Stack Overflow a few days ago (and hopefully a useful answer), I got to thinking a bit about how I use PowerShell. It may be a bit geekish, but PowerShell starts up on Windows startup for me. The prompt is almost always open on a second monitor–ready for whatever task I may need.

As the SO post mentioned, I also use PowerShell to connect to my Git repositories. At the office, it has a few more customizations to hashout against our *shudder* SourceSafe */shudder* repositories, but that’s a different post.

For now, I wanted to walk through how profile script is setup in a bit more detail than the SO post.

A profile script is essentially a “startup” script for your PowerShell environment.

By default (perhaps a registry key changes this), it’s located in %userprofile%\Documents\WindowsPowerShell and is aptly named Microsoft.PowerShell_Profile.ps1. The naming convention between “WindowsPowerShell” and “MicrosoftPowerShell” is a bit annoying, but not a big problem.

The file is just plain text, so feel free to use your editor of choice or PowerShell ISE (Windows 7, Windows 2008 R2) for some fancy content highlighting.

What goes in here?

As far as I can tell, the profile is a great place to initialize global customizations:

environmental variables,

paths,

aliases,

functions that you don’t want extracted to .ps1 files,

customizatons to the console window,

and, most importantly, customize the command prompt.

The Console

I use Console2 rather than the standard PowerShell prompt. Console2 is an amazing open source alternative to the standard console and includes features such as ClearType, multiple tabs, and more. Check it out.

I also use Live Mesh, so there are a few things that are unnecessary for most users. Live Mesh is an online syncronization service… so my PowerShell scripts (amongst other things) stay synced between my home and work environments.

Preparing the Environment

My profile script starts off by setting up a few global variables to paths. I use a quick function to setup the parameters based on the computer I’m currently using.

Easy enough. I’m sure I could optimize this a bit more, but it works. Again, this wouldn’t be necessary on a single computer, but since I use LiveMesh and the same PowerShell profile on multiple computers—this keeps my paths in check.

The second step is to modify the $PATH environmental variable to point to my scripts and Git as well as add a new $HOME variable to satisfy Git’s needs.

The ‘prompt’ function overrides how the command prompt is generated and allows a great deal of customization. As I mentioned in the SO post, the inspiration for my Git prompt comes from this blog post.

I’ve added quite a few code comments in here for reference.

function prompt {

Write-Host(“”)

$status_string = “”

# check to see if this is a directory containing a symbolic reference,

# fails (gracefully) on non-git repos.

$symbolicref = git symbolic-ref HEAD

if($symbolicref-ne$NULL) {

# if a symbolic reference exists, snag the last bit as our

# branch name. eg “[master]”

$status_string += “GIT [“ + `

$symbolicref.substring($symbolicref.LastIndexOf(“/”) +1) + “] “

# grab the differences in this branch

$differences = (git diff-index —name-status HEAD)

# use a regular expression to count up the differences.

# M`t, A`t, and D`t refer to M {tab}, etc.

$git_update_count = [regex]::matches($differences, “M`t”).count

$git_create_count = [regex]::matches($differences, “A`t”).count

$git_delete_count = [regex]::matches($differences, “D`t”).count

# place those variables into our string.

$status_string += “c:” + $git_create_count + `

” u:” + $git_update_count + `

” d:” + $git_delete_count + ” | “

}

else {

# Not in a Git environment, must be PowerShell!

$status_string = “PS “

}

# write out the status_string with the approprate color.

# prompt is done!

if ($status_string.StartsWith(“GIT”)) {

Write-Host ($status_string + $(get-location) + “>”) `

–nonewline –foregroundcolor yellow

}

else {

Write-Host ($status_string + $(get-location) + “>”) `

–nonewline –foregroundcolor green

}

return” “

}

The prompts are then color coded, so I can keep track of where I am (as if the really long prompt didn’t give it away).

Now, with our prompts and our pathing setup to our Git directory, we have all the advantages of Git—in a stellar PowerShell package.

NOTE: I would like to point out that I use PortableGit, not the installed variety. Since Git also moves back and forth across my Live Mesh, it seemed more reasonable to use the Portable version. I don’t believe; however, there would be a difference as long as the \bin directory is referenced.

Setting up Aliases—The Easy Way

Brad Wilson’s implementation of find-to-set-alias is brillant. Snag the script and get ready for aliasing the easy way. I keep my most common tools aliased—Visual Studio, PowerShell ISE, and NotePad. I mean, is there anything else? (Well, yes, but I have Launchy for that).

Using find-to-set-alias is easy—provide a location, an executable, and an alias name:

After getting tired of loading up System.Reflection.Assembly everytime I wanted to see what version of a library I had, I came up with a quick script that dumps out the name of the assembly and the file version.

param(

$file= $(throw “An assembly file name is required.”)

)

$fullpath = (Get-Item$file).FullName

$assembly = [System.Reflection.Assembly]::Loadfile($fullpath)

# Get name, version and display the results

$name = $assembly.GetName()

$version =$name.version

“{0} [{1}]” –f$name.name, $version

With this, running assembly-info NHibernate.dll returns:

NHibernate [2.1.0.4000]

Nifty.

Taking it a step further, I created a quick function in my profile called ‘aia’ or ‘assembly info all’ that runs assembly-info on all .dlls in the directory.

RedGate’s ANTS Performance and Memory profilers can do some pretty slick testing, so why not automate it? The “theory” is that if my coverage is hitting all the high points, I’m profiling all the high points and can see bottlenecks.

So, how does this work? Since the tests are in a compiled library, I can’t just “load” the unit tests. However, you can load Xunit and run the tests.

NOTE: If your profiling x86 libraries on an x64 machine, you’ll need XUnit 1.5 CTP (or later) that includes xunit.console.x86.exe. If you’re on an x86 or do not call x86 libraries, pay no attention to this notice. 😉

To begin, start up ANTS Performance Profiler and Profile a New .NET Executable.

For the .NET Executable, point it towards XUnit and in the Arguments, point it towards the library you are testing. Simple enough.

Click “Start Profiling” and let the profiling begin!

Now if I could just get the “top 10” methods to export to HTML or something so I could automate this in our reporting.