« March 2008 | Main | June 2008 »

May 2008 Archives

May 8, 2008

Integrating Vault and Fortress with Windows PowerShell: Vault-aware Prompt

I've been toying with the idea of integrating Fortress and Vault into Windows PowerShell. PowerShell is, at heart, a scripting wrapper for .NET libraries. Combining that with the Vault Client API (or the equivalent Fortress Client API) seems like a no-brainer.

There are a lot of ways to go here:

  • Creating a provider that would enable Vault/Fortress repositories to be browsed as a file system. You could then just copy files to check them in and out, etc.
  • Re-writing the Vault/Fortress Command Line Client as a series of PowerShell cmdlets would be a reasonably straightforward task.
  • Any number of simple helper functions and convenience commands can be created

For today, not having done and PowerShell scripting before, I'm opting for the last one.

In particular, when I'm in PowerShell, it would be nice to know with Vault/Fortress folder is mapped to my current directory. This is particularly helpful when I have multiple branches of a project in play, and want to see which branch I'm playing with right now.

In action, it looks like this:

At first, we see a typical PowerShell prompt.
PowerShell prompt showing no mapping
In my Documents directory, roughly the same thing.
PowerShell prompt showing no mapping
But Documents\dw-sourcegear maps to the Fortress folder managing sourcegear.com's files. And we see that mapping, grayed, above the prompt.
PowerShell prompt showing Fortress SCC mapping to current directory
Moving further into the tree, the Fortress mapping follows along.
PowerShell prompt showing Fortress SCC mapping to current directory

The fun part is that this took just a few lines of PowerShell code. The API does all the heavy lifting.

What's the catch? This is not the most-comprehensive approach I could have taken -- it's more a proof of concept. We're piggybacking on the Vault/Fortress Command-Line Client's saved login info, so you must have run vault.exe with the REMEMBERLOGIN option at some point. We're also tied to the previously-selected repository.

Correcting those limitations, or implementing the other possibilities mentioned above, is left as an exercise to the reader (or maybe the writer, given a decent chunk of free time)...

The code itself:

## Display SourceGear Fortress/Vault folder mapped to the current directory
## Paul Roub <paul.roub@sourcegear.com>
##

#  did we successfully log in?
$sgLoggedIn = $false 

#  at start up -- attempt to load the Vault lib and log in
#
#  Vault users -- change "Fortress Client" below to "Vault Client"
#
[void] [System.Reflection.Assembly]::LoadFrom($ENV:ProgramFiles + 
   '\SourceGear\Fortress Client\VaultClientIntegrationLib.dll')
$sgLoaded = $true

#  Log in based on previously-saved (via vault.exe) credentials.  Will attach to 
#  the previously-selected repository
#
[VaultClientIntegrationLib.ServerOperations]::Login("Client", $true, $true)
$sgLoggedIn = $true

#  Replace the default command prompt.  This should be loaded via 
#  your profile.ps1 to work properly.
#
function prompt 
{
   #  set the window title to our current dir
   $host.ui.RawUI.WindowTitle = $(get-location)
   
   #  I like a blank line after the last command.  If you don't, 
   #  comment this out.
   Write-Host ""
   
   #  If we didn't log in, don't bother attempting other Fortress operations
   if ($sgLoggedIn)
   {
      #  If there is no mapped folder here, an exception will be thrown.
      #  Catch it, note the lack of a mapping, and continue.
      trap [Exception] 
      {
         $sgFolder = $false
         continue;
      }
      
      #  Grab the mapped folder as an object
      $sgFolder = 
        [VaultClientIntegrationLib.RepositoryUtil]::FindVaultFolderAtReposOrLocalPath($pwd)
      
      if ($sgFolder)
      {
         #  Get the full repository path, and display it in gray above 
         #  the regular prompt
         $sgPath = $sgFolder.FullPath
         $pval = "(" + $sgPath + ")" 
         Write-Host ($pval) --foregroundcolor Gray
      }
   }
   
   #  Whatever we return will be displayed as the remainder of the prompt
   "PS> "
}

May 9, 2008

Win Vault or Fortress licenses at the Tulsa School of Dev this weekend

We've donated several license bundles as giveaways at the School of Dev event this weekend, in Tulsa, OK.

Up for grabs for attendess: 2 five-user Fortress licenses, 2 five-user Vault licenses.

As always, if you're looking for giveaways, swag, $$$, etc. for your user group or code camp -- drop me a line at paul.roub@sourcegear.com

May 23, 2008

Creating Fortress Work Items from the PowerShell command line

Thought I'd pass on another PowerShell script I've been playing with. As before, this is bare-bones -- exception handling, usage, help are all missing. But it's doing what I need it to do this morning.

Again, we're using the Fortress Client Integration library, but this time it's a standalone script that you run explcitily. In this case, we're creating simple Fortress Work Items.

The same caveats apply as before -- run vault.exe's REMEMBERLOGIN command at least once before using this script. You'll also need to know the name of the Fortress project you're adding to (the actual name as displayed, no internal ID numbers, etc are neeed).

The script wants the project name, and a description of the bug being added. Quote them if spaces are involved. We'll default the rest of the fields, using values that are present in any new Fortress installation.

Feel free to test this out against fortressbeta.sourcegear.com, by the way. To add to the single project living there, you'd say:

AddFortressItem "Fortress Demo" "Just testing PowerShell, nothing to see here"

Save the following script somewhere in your PoSH path, and name it AddFortressItem.ps1

# AddFortressItem.ps1
# usage: AddFortressItem "Project Name" "Bug summary"

# Paul Roub <paul.roub@sourcegear.com>

param (
        $projectName = $(throw "Please specify the project name"),
        $subject = $(throw "Please specify the bug description")
)

if (! $sgLoggedIn)
{
        if (! $sgLoaded)
        {
                #  at start up -- attempt to load the Vault lib and log in
                #
                #  Vault users -- change "Fortress Client" below to "Vault Client"
                #
                [void] [System.Reflection.Assembly]::LoadFrom(
                        $ENV:ProgramFiles + 
                        '\SourceGear\Fortress Client\VaultClientIntegrationLib.dll')
                $sgLoaded = $true
        }

        #  Log in based on previously-saved (via vault.exe) credentials.  
        #  Will attach to the previously-selected repository
        #
        [VaultClientIntegrationLib.ServerOperations]::Login(
                "Client", $true, $true)
        $sgLoggedIn = $true
}

$newitem = New-Object "VaultClientIntegrationLib.FortressItemExpanded"

#       use the project name and subject from the command line,
#       default the rest
#       
$newitem.ProjectName  = $projectName
$newitem.Description  = $subject
$newitem.Details      = $subject
$newitem.ItemType     = "Bug"
$newitem.Status       = "Open"
$newitem.Platform     = "Unknown"
$newitem.TimeEstimate = "Unknown"
$newitem.Priority     = "Unknown"

#       check the item and get it ready to add
#
$newitem.Validate()

$res = [VaultClientIntegrationLib.ItemTrackingOperations]::ProcessCommandAddFortressItem(
        $newitem)

echo "Added item:" $res.GetMantisItem().ID

About May 2008

This page contains all entries posted to Paul Roub in May 2008. They are listed from oldest to newest.

March 2008 is the previous archive.

June 2008 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Paul Roub
SourceGear
Work:
115 North Neil St. #408
Champaign, IL 61820-4024
USA
work: +1-217-356-0105 x722