home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 1998 October
/
PCWorld_1998-10_cd.bin
/
software
/
prehled
/
komix
/
DATA.Z
/
contcomman.tcl
< prev
next >
Wrap
Text File
|
1997-11-20
|
18KB
|
661 lines
#---------------------------------------------------------------------------
#
# (c) Cayenne Software Inc. 1997
#
# File: @(#)contcomman.tcl /main/titanic/15
# Author: <generated>
# Description:
#---------------------------------------------------------------------------
# SccsId = @(#)contcomman.tcl /main/titanic/15 20 Nov 1997 Copyright 1997 Cayenne Software Inc.
# Start user added include file section
require platform.tcl
# End user added include file section
require_module_file "vscommand.tcl" vcm
# This class represents all knowledge about Continuus Commands.
Class ContCommand : {VSCommand} {
method destructor
constructor
method addOption
method addArgument
method deleteArguments
method classifyOutput
method execute
# List of command options. Convenient to specify the options in a platform independent
# way. This is because Continuus uses different option specifiers on Unix (-) and Windows (/).
#
attribute optionList
attribute arguments
}
global ContCommand::contCommand
set ContCommand::contCommand "ccm"
global ContCommand::contPath
set ContCommand::contPath ""
# The path of the current ccm work area.
#
global ContCommand::ccmWorkArea
set ContCommand::ccmWorkArea ""
# If the corporate path property contains
# an absolute path, it is stored in this
# variable during init of Continuus vars,
# in forward slash format.
#
global ContCommand::contPathIgnore
set ContCommand::contPathIgnore ""
method ContCommand::destructor {this} {
# Start destructor user section
# End destructor user section
$this VSCommand::destructor
}
constructor ContCommand {class this command argument description} {
set this [VSCommand::constructor $class $this $command $description]
$this command "${ContCommand::contCommand} $command"
$this optionList {}
if { $argument != "" } {
$this arguments [list $argument]
}
return $this
}
# Get a command to checkout the specified Continuus object.
#
proc ContCommand::checkOut {path comment} {
set checkOutCommand [ContCommand new "co" "$path" "Checkout $path"]
$checkOutCommand addOption "c \"$comment\""
return $checkOutCommand
}
# Get a command to create the specified object.
#
proc ContCommand::createObject {path type comment task} {
# Remove spaces from file name
set filePath [path_name directory $path]
set fileName [file tail $path]
regsub -all " " $fileName "" fileName
set path [path_name concat $filePath $fileName]
if { $type == "" } {
set type "ascii"
}
set createCommand [ContCommand new "create" "$path" "Create $path"]
if { $comment != "" } {
$createCommand addOption "c \"$comment\""
}
$createCommand addOption "t $type"
if { $task != 0 } {
$createCommand addOption "task $task"
}
return $createCommand
}
proc ContCommand::deleteObject {path} {
set deleteCommand [ContCommand new "delete" "$path" "Delete $path"]
return $deleteCommand
}
# Get a command to delete and replace the version
# specified by path.
#
proc ContCommand::deleteVersion {path} {
set deleteCommand [ContCommand new "delete" "$path" "Delete and replace $path"]
$deleteCommand addOption "replace"
return $deleteCommand
}
# Get a command to unuse and replace the version
# specified by path.
#
proc ContCommand::unuseVersion {path} {
set unuseCommand [ContCommand new "unuse" "$path" "Unuse and replace $path"]
$unuseCommand addOption "replace"
return $unuseCommand
}
# Return a command to set the value of the specified attribute.
#
proc ContCommand::setAttribute {path name value} {
set setCommand [ContCommand new "attribute" "$path" "Set attribute $name"]
$setCommand addOption "c $name"
$setCommand addOption "f"
$setCommand addOption "t string"
$setCommand addOption "v \"$value\""
return $setCommand
}
# Get a command to reconfigure e.g. update the work
# area in path.
#
proc ContCommand::reconfigure {path} {
return [ContCommand new "reconfigure" "$path" "Update work area in $path"]
}
proc ContCommand::rename {oldPath newPath} {
set renameCommand [ContCommand new "move" "$oldPath" "Move $oldPath"]
$renameCommand addArgument $newPath
return $renameCommand
}
proc ContCommand::checkOutDialog {} {
set checkOutDialog [ContCommand new "co" "" "Checkout Dialog"]
$checkOutDialog addOption "g"
return $checkOutDialog
}
proc ContCommand::checkInDialog {} {
set checkInDialog [ContCommand new "ci" "" "Check in dialog"]
$checkInDialog addOption "g"
return $checkInDialog
}
proc ContCommand::checkInTaskDialog {task} {
set checkInTaskDialog [ContCommand new "ci" "" "Check In Task Dialog"]
$checkInTaskDialog addOption "g"
$checkInTaskDialog addOption "task $task"
return $checkInTaskDialog
}
proc ContCommand::findUseDialog {} {
set findUseDialog [ContCommand new "finduse" "" "Find Use Dialog"]
$findUseDialog addOption "g"
return $findUseDialog
}
proc ContCommand::propertyDialog {} {
set propertyDialog [ContCommand new "prop" "" "Property Dialog"]
$propertyDialog addOption "g"
return $propertyDialog
}
proc ContCommand::historyDialog {} {
set historyDialog [ContCommand new "history" "" "History Dialog"]
$historyDialog addOption "g"
return $historyDialog
}
proc ContCommand::useDialog {} {
set useDialog [ContCommand new "use" "" "Use Dialog"]
$useDialog addOption "g"
return $useDialog
}
# Get command to bring up task selection dialog.
#
proc ContCommand::selectTaskDialog {} {
set selectTaskDialog [ContCommand new "task" "" "Select Task Dialog"]
$selectTaskDialog addOption "g"
return $selectTaskDialog
}
# Return a command for diffing the current version of path with the
# version specified.
#
proc ContCommand::diff {path version} {
set file [file tail $path]
set command "diff [quoteIf $file-$version] [quoteIf $file]"
set diffCommand [ContCommand new "$command" "" "Show diff"]
return $diffCommand
}
proc ContCommand::objectMakeDialog {} {
set objectMakeDialog [ContCommand new "make" "" "Start ObjectMake"]
$objectMakeDialog addOption "g"
return $objectMakeDialog
}
proc ContCommand::queryDialog {} {
set queryDialog [ContCommand new "query" "" "Start Query Dialog"]
$queryDialog addOption "g"
return $queryDialog
}
proc ContCommand::problemTrackingBrowser {} {
set problemDialog [ContCommand new "pt" "" "Start Problem Tracking"]
$problemDialog addOption "g"
return $problemDialog
}
# Get specified version in file specified by destPath.
#
proc ContCommand::getVersion {path version destPath} {
if $win95 {
set command "type [list $path-$version] > [list $destPath]"
} else {
set command "cat [list $path-$version] > $destPath"
}
set catCommand [ContCommand new "$command" "" "Retrieve $path-$version"]
return [vsCommandHandler executeSilent $catCommand]
}
# Return a list of version identifiers for all versions of this object.
#
proc ContCommand::candidates {path} {
set candidatesCommand [ContCommand new "candidates" "$path" \
"Retrieving version of $path"]
if { ![vsCommandHandler executeSilent $candidatesCommand] } {
return ""
}
set versionList {}
foreach line [split [$candidatesCommand output] "\n"] {
set version [lindex $line 1]
# retrieve version identifier from full version name
regexp {\-[^-]+$} $version versionPart
lappend versionList [string range $versionPart 1 end]
}
return $versionList
}
# returns whether the specified path refers
# to a Continuus element.
#
proc ContCommand::existsInContinuus {path} {
# just test existence for performance reasons
return [file exists $path]
}
# Return the version identifier of the predecessor of this object.
# If there are more return just one. Currentversion is the current version.
#
proc ContCommand::getPredecessor {path currentVersion} {
# do a history and parse output to get the information
set historyCommand [ContCommand new "hist" "$path" "Retrieve history of"]
$historyCommand addOption "f \"%name %version\""
if { ![vsCommandHandler executeSilent $historyCommand] } {
return
}
set fileName [file tail $path]
set parseVersion ""
set inPredListing 0
foreach line [split [$historyCommand output] "\n"] {
if { "[lindex $line 0]" == "$fileName" } {
set parseVersion [lindex $line 1]
}
if $inPredListing {
if { "$parseVersion" == "$currentVersion" } {
# Check if there are any predecessors
# if not this is a Successors: line
if [regexp {Successors:.*} $line] {
return ""
}
# Bingo! This is the one. Get version id
regsub "$fileName\-" $line "" versionPart
regexp {[^:]*} [string trim $versionPart] versionId
return $versionId
}
}
if [regexp {Predecessors:.*} $line] {
set inPredListing 1
} else {
set inPredListing 0
}
}
# Not found
return ""
}
# Return the value of the specified attribute.
#
proc ContCommand::getAttributeValue {path name} {
global VSFile::classAttribute
set getCommand [ContCommand new "ls" "$path" "Get attribute $name"]
$getCommand addOption "f %${VSFile::classAttribute}"
if { ![vsCommandHandler executeSilent $getCommand] } {
return ""
}
set value [string trim [$getCommand output]]
if { $value == "<void>" } {
return ""
}
return $value
}
# Initialize the ccm variables:
# CcmWorkArea.
#
proc ContCommand::initializeCcmVars {} {
global ContCommand::ccmWorkArea
global ContCommand::contPathIgnore
# check corporate path
set corporate [[ClientContext::global] currentCorporate]
if [$corporate isA Corporate] {
set corpPath [$corporate getPropertyValue fileSystemPath]
if { [file pathtype $corpPath] != "relative" } {
set ContCommand::contPathIgnore \
[eval file join [file split $corpPath]]
}
}
# check if CCM_WA_BASE is set, use it if so
if [catch { set wa $env(CCM_WA_BASE) }] {
set homeDir [M4Login::getHomeDir]
set defaultWaDir [path_name concat $homeDir ccm_wa]
if { ![file isdirectory $defaultWaDir] } {
vsCommandHandler error "Work Area Directory not found"
return 0
}
# take first database directory we find
set oldDir [pwd]
cd $defaultWaDir
if [catch { set files [glob *] }] {
cd $oldDir
vsCommandHandler error "No databases found in $defaultWaDir"
return 0
}
set databaseDir ""
foreach file $files {
if [file isdirectory $file] {
set databaseDir $file
break
}
}
cd $oldDir
if { $databaseDir == "" } {
vsCommandHandler error "No directories found in $defaultWaDir"
return 0
}
# set in global static variable
set ContCommand::ccmWorkArea [path_name concat \
$defaultWaDir $databaseDir]
return 1
}
set ContCommand::ccmWorkArea $wa
return 1
}
# Do a formatted listing in the specified directories and get:
# Version, Owner, Status, Continuus Type, Created, Modified, Platform, Release, Task, Instance.
#
proc ContCommand::longListing {pathList infoDict} {
set existingPaths {}
foreach path $pathList {
if [file isdirectory $path] {
lappend existingPaths $path
}
}
if [lempty $existingPaths] {
return ""
}
# make command: set format options and add all paths
set lsCommand [ContCommand new "ls" "" "long listing"]
global VSFile::classAttribute
set optionString "f \"%name %version %owner %status %type \\\"%create_time\\\" \\\"%modify_time\\\" \\\"%platform\\\" \\\"%release\\\" \\\"%task\\\" \\\"%${VSFile::classAttribute}\\\" %instance\""
$lsCommand addOption $optionString
foreach path $existingPaths {
$lsCommand addArgument $path
}
# Execute Continuus command
if { ![vsCommandHandler executeSilent $lsCommand] } {
return ""
}
# parse the output and put it in dictionary
# use name as key, all other items as valuelist
if { [llength $existingPaths] == 1 } {
set fullPath [lindex $existingPaths 0]
} else {
regexp "(\[^ \]*) .*" $existingPaths dummy fullPath
}
foreach line [split [$lsCommand output] "\n"] {
if { [string trim $line] == "" } {
continue
}
# if multiple paths are used there is directory info
# in the output
if { [regexp {^[^ :]*:$} $line dirName] } {
if { [llength $existingPaths] == 1 } {
set fullPath [lindex $existingPaths 0]
} else {
regexp "(\[^ \]*) (.*)" $existingPaths dummy fullPath existingPaths
}
continue
}
set name [lindex $line 0]
set type ""
if { [llength $line] > 4 } {
set type [lindex $line 4]
}
if { $type == "dir" } {
continue
}
set valueList [lrange $line 1 end]
$infoDict set [path_name concat $fullPath $name] $valueList
}
}
# Do a Continuus listing in the specified directories
# and return a list of filenames.
#
proc ContCommand::shortListing {pathList} {
set existingPaths {}
foreach path $pathList {
if [file isdirectory $path] {
lappend existingPaths $path
}
}
if [lempty $existingPaths] {
return ""
}
# make command: set format options and add all paths
set lsCommand [ContCommand new "ls" "" "long listing"]
$lsCommand addOption "f \"%name %type\""
foreach path $existingPaths {
$lsCommand addArgument $path
}
# Execute Continuus command
if { ![vsCommandHandler executeSilent $lsCommand] } {
return ""
}
set fileList {}
if { [llength $existingPaths] == 1 } {
set fullPath [lindex $existingPaths 0]
} else {
regexp "(\[^ \]*) .*" $existingPaths dummy fullPath
}
foreach line [split [$lsCommand output] "\n"] {
if { [string trim $line] == "" } {
continue
}
if { [regexp {^[^ :]*:$} $line dirName] } {
if { [llength $existingPaths] == 1 } {
set fullPath [lindex $existingPaths 0]
} else {
regexp "(\[^ \]*) (.*)" $existingPaths dummy fullPath existingPaths
}
continue
}
set name [lindex $line 0]
set type ""
if { [llength $line] > 1 } {
set type [lindex $line 1]
}
if { $type == "dir" } {
continue
}
lappend fileList [path_name concat $fullPath $name]
}
return $fileList
}
# Get the comment for the specified object.
#
proc ContCommand::getComment {path} {
set commentCommand [ContCommand new "attr" "$path" "Get comment of $path"]
$commentCommand addOption "show comment"
if { ![vsCommandHandler executeSilent $commentCommand] } {
return ""
}
return [$commentCommand output]
}
# Get the working versions of the named project
# owned by the current user.
#
proc ContCommand::getWorkingProjectVersions {project} {
set queryCommand [ContCommand new "query" "" "Get working project versions"]
$queryCommand addOption "f %version"
$queryCommand addOption "n $project"
$queryCommand addOption "o [M4Login::getUserName]"
$queryCommand addOption "t project"
$queryCommand addOption "s working"
if { ![vsCommandHandler executeSilent $queryCommand] } {
return ""
}
set versionList {}
foreach line [split [$queryCommand output] "\n"] {
# output returns first sequence number and then version name
lappend versionList [lindex $line 1]
}
return $versionList
}
# Get the continuus type of the specified file.
#
proc ContCommand::getContinuusType {path} {
set lsCommand [ContCommand new "ls" "$path" "get type"]
$lsCommand addOption "f %type"
# Execute Continuus command
if { ![vsCommandHandler executeSilent $lsCommand] } {
return ""
}
return [$lsCommand output]
}
# Add option to optionList.
#
method ContCommand::addOption {this option} {
set list [$this optionList]
lappend list $option
$this optionList $list
}
# Add argument to argument list.
#
method ContCommand::addArgument {this argument} {
$this arguments "[$this arguments] [list $argument]"
}
method ContCommand::deleteArguments {this} {
$this arguments ""
}
method ContCommand::classifyOutput {this} {
# not necessary for Continuus
}
# Construct the command from command, optionList and argumentList and execute it.
#
method ContCommand::execute {this classifyOutput} {
set commandString "exec [$this command]"
# make option list
foreach option [$this optionList] {
if $win95 {
set commandString "$commandString /$option"
} else {
set commandString "$commandString \-$option"
}
}
# add arguments
# with one argument, cd to the directory
# and execute there
set arguments [$this arguments]
set oldDir [pwd]
if { [llength $arguments] == 1 } {
set directory [string trim [path_name directory [lindex $arguments 0]]]
if [ catch { cd $directory }] {
$this errors "Directory $directory not found"
return
}
set commandString "$commandString [list [file tail [lindex $arguments 0]]]"
} else {
set commandString "$commandString $arguments"
}
# Execute it
if [ catch { set output [eval $commandString] } errors] {
cd $oldDir
# continuus Commands return strange exit status sometimes
# ignore resulting tcl output
regsub {child process exited abnormally} $errors "" errors
$this errors $errors
return
}
cd $oldDir
# Continuus sometimes throws in uninteresting lines in the
# output, remove it...
regsub {.*Updating database.*\.\.\..} $output "" output
$this output $output
if $classifyOutput {
$this classifyOutput
}
}
# Do not delete this line -- regeneration end marker