Paul Roub

A Software Tool Geek in His Natural Habitat

Finding Non-Version-Controlled Files in Vault and Fortress

I’ve been talking to some Vault users who felt that Vault was letting them down — specifically, that the client wasn’t helping them spot newly-added files, and make sure they were checked in. Orphaned files lead to broken builds, gnashing of teeth ensues.

It’s easy to forget this when (as most of us here at SourceGear do) you spend much of your life using and thinking about IDEs. Using Vault and Fortress in Visual Studio or Eclipse, it takes an effort to keep your project’s new files out of version control.

I’ll state up front that we don’t solve this problem as well as we should at the moment, and we’re going to address that. In the meantime, a quick primer on how we do solve the problem — and actually, we do a better job than might be immediately apparent.

There are two ways in which we’ll find new files for you.

Ghosts

The first is via the "Show non-version-controlled files ghosted in the file list" and "Show non-version-controlled folders in the folder tree" options. With these enabled, viewing a directory in Vault will show grayed-out, "ghosted" entries for files (or folders) in the working directory, but not in Vault, like so:

The problem is, especially for new files, this is a folder-at-a-time feature. There’s no at-a-glance way to see all new files in all subfolders.

Detect New Files to Add

This is better handled by the Detect New Files to Add feature. What’s not immediately obvious is how that feature does allow recursive searching of a folder. An example may help.

Here’s a simple folder structure — one subfolder, a few files.

Some of these files are checked in to Fortress, some are not:

We fire up Detect New Files to Add

And initially, we see the new file in the root folder (the one folder we’re currently viewing).

We check the box next to "dwtest", and Fortress searches this folder and all of its known subfolders, to find non-version-controlled files. Note that the .dll file we saw earlier is ignored — there’s a predefined list of file types to exclude from searches like this (which can, of course, be modified on the fly or via the Admin tools).

But what if we don’t want to add all of those files? No problem. Select any files you want to kick off the list, then click Remove.

Add a comment, or not, then click OK to add everything still on the list.

What’s missing?

The most glaring omission here is that we detect new files only. If you’ve added a new folder, Detect New… won’t spot it. Luckily, this is a much-less-common occurrence, and less likely to go unnoticed. But still. Needs to be better. And it will be.

Speak up

(Hopefully) needless to say, while I’m always happy to hear praise for our products, I’m just as eager to hear what’s not working for you. Have a Vault or Fortress pet peeve? A most-missed nonexistent feature? Don’t hesitate to let me know.

A Little Ammo

Often, and ideally, version control, bug tracking and other dev tools are chosen in a grassroots manner. Programmers find the tools they want / need / like, and become unpaid evangelists, or vigilante marketers, or whatever phrasing would read best on a T-shirt. I was always one of those guys, going back to promoting RCS as the go-to tool for the Xenix environment at my first summer internship.

Now I’m paid to help those people – if I’m doing my job, they’re the target audience for most anything I do. Sometimes, that’s lobbying to push the features they want higher on the priority list (often because I want them, too). And sometimes, it’s being asked for “a little ammo” by someone who wants his team to move to Vault. But his manager knows Subversion is free, and doesn’t see why Vault would be such a better fit for their team that they’d spend money on it.

So for that guy, and the other guy asking for the same thing a day or two later, we’ve posted a “Vault vs Subversion” white paper. It’s short (so your manager will be willing to read it), mostly non-technical (ditto), and focuses on the reasons a Windows-based shop will often find Vault an easier, better, cheaper-in-the-long-run fit. It might also convince a fully-Linux-based shop, using an IDE we don’t support, standardized on MySQL as the sole database platform, that Vault is not the best fit for them. Either way, time saved, questions cleared.

Expect “Vault vs VSS” and “Vault vs CVS” papers in the future, when I can figure out how to expand them beyond “well, duh”.

It’s Code Camp Season!

Or so it would appear.

We’re co-sponsoring 4 upcoming code camps at the moment - contributing money, swag, and Fortress giveaways. And we’d be happy to help out with yours (or your user group meeting) as well – just let me know

Here’s the list as it stands at the moment:

Southwest Florida Code Camp: Saturday, September 13, Estero, FL

Central Coast Code Camp: Saturday and Sunday, September 27th and 28th, San Luis Obispo, CA

Argentina Code Camp: Saturday, October 4, Universidad Abierta Interamericana

Jacksonville Code Camp: Saturday, October 23, Jacksonville, FL

Explaining Fortress Visually

One of my recent pet projects is to add a number of videos to the Fortress section of sourcegear.com. Currently, “a number” translates to “three”.

Basically, we’d noticed that while Version Control concepts and features can often be nicely explained in screenshots and text, it’s harder to do on the bug tracking / ALM side of things. Especially when we’re dealing with combined Bug Tracking and Version Control features, and their interaction with IDEs, etc.

But these things are easy, and fun, to show – as we do at trade shows, in person, in our online demos, etc. So the plan is to get as much of that info up on the site as possible.

Why is line history so cool? Let me show you.

How do Fortress “clouds” help you find your way through a forest of Work Items? Let me show you.

And the latest – we’re always encouraging people to take a look at Fortress for themselves. The download’s not huge, the requirements are slight, and installation is quick. But everyone says that, and the installation’s never quick.

So really, how quick? “Minutes”? Really? Take a look.

Notes on TechEd 2008

TechEd/developers 2008 was a lot of fun, and extremely tiring.  The combination of plans gone astray, unplanned events, and things which couldn’t be planned for kept life interesting.

Plans Gone Astray

As at SD West, we had announced that we’d be giving away Fortress licenses to those who could beat Jeremy at Guitar Hero.  Gauntlets were thrown. Smack was talked.

And then Jeremy had to fly back home, unexpectedly, before the show started.  Our Artistic Director, John Woolley (the man behind the Evil Mastermind) bravely stepped into the breach and took on all comers.

John’s good, but by his own admission not freakishly good like Jeremy.  He still turned in a near 50/50 win/loss ratio.  It probably would have been higher if I hadn’t stepped in for a few rounds.

The gallery of winners can be seen at flickr

Also, it certainly seemed like 900 shirts would last at least a few days.  As opposed to barely squeaking through the first day.

Unplanned Events

Things I learned while setting up for the show.  Or, things which should have been completely obvious beforehand:

  1. Show setup day, on site, is not the time and place to install OS updates.
  2. Especially Windows Service Packs.
  3. Always check that you have the very latest drivers for your video card, before replacing it when it stops speaking to a Cinema display.
  4. Especially following a Service Pack update.

Fun times.  All worked out eventually. 

How Do You Plan For…

The TechEd Jam Sessions?

We did slightly, of course.  But Jeremy was our bass player, so some additional uncertainty was thrown in.  An Expo day pass for my brother gave us a ringer on drums, at least :-)

So up we go, Eric on acoustic guitar, me on the Evil Mastermind Schecter, Brad on drums, and a cast of several on guitars, keys, bass, percussion.  All watching and listening as we shouted or showed chord changes.  And it went pretty well just the same.

Sadly, the battery died in the camcorder a minute and a half in.  Also not according to plan.  But here’s what we do have:

Pinball Wizard at the TechEd 2008 Jam Session

Next up…

PDC and DevConnections in the fall.  Plenty of time to plan.

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

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> "
}