Main

Tools Archives

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

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

November 29, 2007

Vault! Fortress! Ack!

I've fallen in love with a new tool known as ack. It's basically grep, the way I want grep to work when coding:

  • Full Perl regular expressions
  • Iterates over directories by default
  • Skips source control directories (q.v.)
  • Easily restricted to certain file types

So if I'm searching a tree of Perl files, instead of something like:

grep pattern $(find . -name '*.pl' -or -name '*.pm' -or -name '*.pod' | \
  grep -v _sgbak)

(to find Perl program, module, and POD files, skipping anything in Vault/Fortress _sgbak folders), I can just say:

ack --perl pattern

And yes, as of version 1.74, ack includes Vault and Fortress in its list of supported version control tools. So if I want to see references to the explodeMinion46 function, I can just say:

ack explodeMinion46

To recursively search my current directory, avoiding backup files along the way.

There are a number of other options, including configuring your own exclusions, etc. on the fly -- but for me, the out-of-the-box behavior is now exactly what I want.

About Tools

This page contains an archive of all entries posted to Paul Roub in the Tools category. They are listed from oldest to newest.

SourceGear is the previous category.

User Groups is the next category.

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