COMPANY: AccuRev, Inc.

AccuRev , Acquired in 2013 by MicroFocus who in 2009 also acquired Borland, is a proprietary centralized SCM system.

Description

TkDiff is integrated into AccuRev. A Tk GUI was being developed at one point. The maintenance of tkdiff was picked up by this company when the original author was unable to continue maintenance.


I started using AccuRev when I moved to my new job, and I found that I would often forget which streams were backing my current workspace. There isn't an accurev command line option for this, so I wrote a Tcl script. I decided to make a package for AccuRev first, then include it. The code is sloppy and thrown together in a quick fit of annoynce so I'd expect anyone picking it up to improve it. When I do, I'll change it here. I'd rather do something that didn't have me calling out to exec everytime I recursed.

First, parents:

#! /opt/ActiveTcl/bin/tclsh
# parents

package require tcl_acrev

set stream [lindex $argv 0]

if {($stream != {}) || ![catch {set stream [tcl_acrev::get_cwd_wspace]}]} {
    puts $stream
    if {[catch {tcl_acrev::get_ancestry $stream} ec]} {
        puts "help, I don't know how to find your parents: $ec"
    }
} else {
    puts "help, I don't know how to find your parents $stream"
}

Here is the package. again, sloppy.

package provide tcl_acrev 1.0

namespace eval tcl_acrev {}

proc tcl_acrev::acupdate {} {
    if {[catch {exec accurev update} result]} {
        error $result
    }
    puts $result
}

proc tcl_acrev::acstat {{flag n}} {
    if {[catch {exec accurev stat -$flag} result]} {
        error $result
    }
    return $result
}
 
proc tcl_acrev::get_statted_files {{flag n}} {
    set stat_result [split [tcl_acrev::acstat $flag] \n]
    set file_list {}

    foreach line $stat_result {
        foreach {path stream version state} $line {
            lappend file_list $path
        }
    }
    return $file_list
}


proc tcl_acrev::updatepath {path} {
    if {![file isdirectory $path]} {
        error "$path is not a directory"
    }
    puts "updating $path"
    set cwd [pwd]
    cd $path
    set fail [catch {acupdate} ec]
    cd $cwd
    if {$fail} {
        puts "couldn't update $path: $ec"
    }
}

proc tcl_acrev::show_stream {stream} {

    if {![regexp {\d|\w|-} $stream]} {
        error "invalid arg ($stream)"
    }
    if {[catch {set accurev_show [exec accurev show -s $stream streams]} ec]} {
        error "$ec"
    }

    foreach {s basis depot number} [lindex [split $accurev_show \n] 1] {break}

    puts "$basis"

    return [list $basis $depot $number]
}

proc tcl_acrev::get_cwd_wspace {} {
    set wspace {}
    if {[catch {set info [exec accurev info]} ec]} {
        error "$ec"
    }
    regexp {ws/ref:\s+(\S+)} $info m wspace
    return $wspace
}

proc tcl_acrev::get_basis {stream} {
    return [lindex [show_stream $stream] 0]
}

proc tcl_acrev::get_depot {stream} {
    return [lindex [show_stream $stream] 1]
}

proc tcl_acrev::get_ancestry {stream} {
    if {$stream eq {--}} {
        return $stream
    }
    set basis [get_basis $stream]
    return [list $stream [get_ancestry $basis]]
}

snichols:

From the command line, this command will also give your basis or your backed Accurev stream in XML format:

accurev show -fx -s <insert_your_workspace_name> streams.

Then you can use an XML parser such as tdom to parse the result instead of screen scraping. But wait, what if you don't even know the name of your workspace? You can find this out by running the following Linux or Windows command:

accurev show -fx wspaces

This will return an XML resultset. Then parse the the Name XML attibute in each Element element, and run the other command above to get the basis. You could also walk all streams recursively until you get to the depot to find all streams in the heiarchy.

Are you looking for a Tcl script that wraps all the AccuRev command line calls and parses the results and stores in collections (Tcl List, Array, or Dictionary)?


skm: btw, there's a command to list all of the streams for you, you don't need to generate it. spice with -fx as needed.

accurev show -p <depot name> streams

Is it generally a better practice for me to retrieve the XML-formatted output for use in scripts? I didn't want to write a script that required work for non tcl users to the tune of "oh great, she wrote this script in a language I don't use and now I have to go find special libraries" so I avoided using tdom. I figure most anyone here would have access to a tclsh without all of the batteries included.

Here's some sample output so you can see what I wanted. I like listing things very simply. I'd prefer not to read xml, so even if I did end up using that I'd massage it into something like this.

[~/work/austin/lib-hmp]$ parents
orbitz-lib-hmp-wksp_smiguez
orbitz-lib-hmp-austin-smiguez
orbitz-lib-hmp-austin-itinerary
orbitz-lib-hmp-5-rc
orbitz-lib-hmp

My main goal was to just to get a parentage list (not just the immediate predecessor), but I'll probably write more CLI scripts as the need arises. Don't want to do everything all at once.

I wrote another script I am not sharing since it is messy and probably only satisfies my idiosyncratic work flow -- I wrote an updateall script to visit all the subdirectories one level down from the current directory to call update on them. I tend to organize some of my projects that way and have to work with a lot of depots.


snichols:

Regarding your comment, "Is it generally a better practice for me to retrieve the XML formatted output for use in scripts?"

I consider Tcl to be a script too and it has several XML parsers to choose from. You can always return the result to screen in a non-XML format like you mentioned after the XML has been parsed.