home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 1998 October
/
PCWorld_1998-10_cd.bin
/
software
/
prehled
/
komix
/
DATA.Z
/
cccommand.tcl
< prev
next >
Wrap
Text File
|
1997-11-25
|
23KB
|
833 lines
#---------------------------------------------------------------------------
#
# (c) Cayenne Software Inc. 1997
#
# File: @(#)cccommand.tcl /main/titanic/16
# Author: <generated>
# Description:
#---------------------------------------------------------------------------
# SccsId = @(#)cccommand.tcl /main/titanic/16 25 Nov 1997 Copyright 1997 Cayenne Software Inc.
# Start user added include file section
# End user added include file section
require_module_file "vscommand.tcl" vcm
# This class knows everything about ClearCase commands.
Class CCCommand : {VSCommand} {
method destructor
constructor
method classifyOutput
method execute
}
# The name of the cleartool command.
#
global CCCommand::cleartoolCommand
set CCCommand::cleartoolCommand "cleartool"
# This contains the cleartool path, it is set
# during system initialization and only used on Windows.
#
global CCCommand::cleartoolPath
set CCCommand::cleartoolPath ""
method CCCommand::destructor {this} {
# Start destructor user section
# End destructor user section
$this VSCommand::destructor
}
constructor CCCommand {class this command path description} {
set this [VSCommand::constructor $class $this $command $description]
# Start constructor user section
global CCCommand::cleartoolCommand
if { $path != "" } {
set command "$command [quoteIf $path]"
}
$this command "${CCCommand::cleartoolCommand} $command"
# End constructor user section
return $this
}
# Get a command to chheck out a ClearCase object.
#
proc CCCommand::checkOut {path comment reserved} {
set command "co "
if { $comment == "" } {
append command "-nc"
} else {
append command "-c \"$comment\""
}
if { !$reserved } {
set command "$command -unreserve"
}
return [CCCommand new "$command" "$path" "Checkout $path"]
}
# Get a command to check in a ClearCase object.
#
proc CCCommand::checkIn {path noComment comment} {
set tempFile ""
if $noComment {
set command "ci -nc"
} else {
# normally we would just pass the empty comment to the command line
# however, on Windows CC freaks on this. So we just make an empty
# file for this case and use a different command line argument
if { ($comment == "") && $win95 } {
set tempFile [BasicFS::tmpFile]
set command "ci -cfile \"$tempFile\""
} else {
set command "ci -c \"$comment\""
}
}
set checkInCommand [CCCommand new "$command" "$path" "Checkin $path"]
if { $tempFile != "" } {
$checkInCommand addTempFile $tempFile
}
return $checkInCommand
}
# Get a command to un check out a ClearCase object.
#
proc CCCommand::unCheckOut {path keepPrivate} {
if $keepPrivate {
set command "unco -keep"
} else {
set command "unco -rm"
}
return [CCCommand new "$command" "$path" "Uncheckout $path"]
}
# Get a command to create a ClearCase object.
#
proc CCCommand::createElem {path type comment} {
if { $type == "" } {
set type "text_file"
}
set command "mkelem -eltype $type "
if { $comment == "" } {
append command "-nc"
} else {
append command "-c \"$comment\""
}
return [CCCommand new "$command" "$path" "Create file $path"]
}
# Get command to set attribute value on all
# versions of vob element specified in path.
#
proc CCCommand::setAttribute {path name value} {
set command "mkattr -replace $name \\\"$value\\\""
return [CCCommand new "$command" "${path}@@" "set attribute $name"]
}
# Get a command to remove a ClearCase name.
#
proc CCCommand::removeName {path} {
set command "rmname"
return [CCCommand new "$command" "$path" "Delete file $path"]
}
# Get a command to rename a ClearCase object.
#
proc CCCommand::rename {oldPath newPath} {
set command "mv [quoteIf $oldPath] [quoteIf $newPath]"
return [CCCommand new "$command" "" "Rename $oldPath" ]
}
# Get a command to create a ClearCase branch.
#
proc CCCommand::createBranch {path type comment} {
set command "mkbranch "
if { $comment == "" } {
append command "-nc"
} else {
append command "-c \"$comment\""
}
append command " $type"
return [CCCommand new "$command" "$path" "Create branch $type on $path"]
}
# Get a command to destroy a ClearCase branch.
#
proc CCCommand::destroyBranch {path} {
set command "rmbranch -f -nc"
return [CCCommand new "$command" "$path" "Destroy branch"]
}
# Get a command to create a new ClearCase branch type.
#
proc CCCommand::newBranchType {type comment vob} {
set command "mkbrtype "
if { $comment == "" } {
append command "-nc"
} else {
append command "-c \"$comment\""
}
append command " -vob [quoteIf $vob] $type"
return [CCCommand new "$command" "" "New branch type $type"]
}
# Get a command to destroy the specified branch type
# in the specified vob.
#
proc CCCommand::destroyBranchType {type vob} {
set command "rmtype -brtype -vob [quoteIf $vob] $type"
return [CCCommand new "$command" "" "Destroy branch type $type"]
}
# get a command to reserve a ClearCase checkout.
#
proc CCCommand::reserve {path} {
set command "reserve"
return [CCCommand new "$command" "$path" "Reserve $path"]
}
# Get a command to unreserve a ClearCase checkout.
#
proc CCCommand::unreserve {path} {
set command "unreserve"
return [CCCommand new "$command" "$path" "Unreserve $path"]
}
# Get a command to list checkouts of a ClearCase object.
#
proc CCCommand::listCheckout {path} {
set command "lsco"
return [CCCommand new "$command" "$path" "List checkouts of $path"]
}
# Get a command to change the comment for a ClearCase object.
#
proc CCCommand::changeComment {path comment} {
set command "chevent "
if { $comment == "" } {
append command "-nc"
} else {
append command "-c \"$comment\""
}
append command " -replace"
return [CCCommand new "$command" "$path" "Change comment of $path"]
}
# Get command to show diff of selected version
# with specified version.
#
proc CCCommand::diff {path version graphical} {
if $graphical {
set command "xdiff"
} else {
set command "diff -col 160"
}
set command "$command [quoteIf $path\@\@$version] [quoteIf $path]"
return [CCCommand new "$command" "" "Show diff with other version"]
}
# Returns whether the directory specified by
# directory is checked out.
#
proc CCCommand::isCheckedOut {directory} {
set command "lsco -cview -fmt %u -directory"
set lscoCommand [CCCommand new "$command" "$directory" "Get checkout status of $directory"]
vsCommandHandler errorsSuspended 1
if { ![vsCommandHandler executeSilent $lscoCommand] } {
vsCommandHandler errorsSuspended 0
return 0
}
vsCommandHandler errorsSuspended 0
if { [$lscoCommand output] != "" } {
return 1
}
return 0
}
# Return whether the file path refers to exists in the vob.
#
proc CCCommand::existsInVob {path} {
# this should not be called if path does not exist
set command "ls -vob"
set lsCommand [CCCommand new "$command" "$path" "Searching $path in vob"]
if { ![vsCommandHandler executeSilent $lsCommand] } {
return 0
}
if { [$lsCommand output] != "" } {
return 1
}
return 0
}
# Returns the previous version of path.
#
proc CCCommand::getPredecessor {path} {
set command "describe -fmt \"%PVn\""
set descCommand [CCCommand new "$command" "$path" "Get previous version of $path"]
if { ![vsCommandHandler executeSilent $descCommand] } {
return ""
}
return "[$descCommand output]"
}
# Get value of attribute specified by name
# from versions specified by path.
#
proc CCCommand::getAttributeValue {path name} {
set command "describe -s -aattr $name"
set getCommand [CCCommand new "$command" "${path}@@" "Get attribute $name"]
if { ![vsCommandHandler executeSilent $getCommand] } {
return ""
}
regsub -all {"} [string trim [$getCommand output]] "" value
return $value
}
# Executes the remove branch command without
# actually removing and intercepts the remove warning and
# returns it.
#
proc CCCommand::getRemoveBranchWarning {path} {
set command "rmbranch -nc"
set rmCommand [CCCommand new "$command" "$path" "Destroy branch"]
$rmCommand input "no"
# since 3.0 ClearCase returns error exit status on this
# command so use error output in that case
vsCommandHandler errorsSuspended 1
set correctedError 0
if { ![vsCommandHandler executeSilent $rmCommand] } {
$rmCommand output [$rmCommand errors]
set correctedError 1
}
vsCommandHandler errorsSuspended 0
# remove superfluous output from warning
if { ![regsub -all {\[no\]} [$rmCommand output] "" warning] \
&& $correctedError } {
return ""
}
return $warning
}
# Do a ClearCase listing in the specified paths and add following information to infoDict:
# filename, version, checkout status, rule.
#
proc CCCommand::longListing {pathList infoDict} {
set existingPaths {}
foreach path $pathList {
if [file isdirectory $path] {
lappend existingPaths $path
}
}
if [lempty $existingPaths] {
return ""
}
set pathList $existingPaths
set lsCommandString "ls -l "
# uncomment lsd parts for directory support (post titanic?)
# set lsdCommandString "ls -l -dir "
set lscoCommandString "lsco -cview "
foreach path $pathList {
set lsCommandString "$lsCommandString [quoteIf $path]"
# set lsdCommandString "$lsdCommandString [quoteIf $path]"
set lscoCommandString "$lscoCommandString [quoteIf $path]"
}
# execute ClearCase ls commands
set lsCommand [CCCommand new "$lsCommandString" "" "$lsCommandString"]
if { ![vsCommandHandler executeSilent $lsCommand] } {
return
}
# set lsdCommand [CCCommand new "$lsdCommandString" "" "$lsdCommandString"]
# if { ![vsCommandHandler executeSilent $lsdCommand] } {
# return
#}
# set lsOutput "[$lsCommand output]\n[$lsdCommand output]"
set lsOutput [$lsCommand output]
# it succeeded, now format output so the browser understands it
foreach line [split $lsOutput "\n"] {
# it is either 'version' or 'directory version'. Strip directory
# to keep formatting simple
# regsub {^directory.} $line "" line
# for titanic skip directories
if [regexp {^directory.} $line] {
continue
}
if { ![regexp "^version" $line] } {
if { ![regexp {no version selected} $line] } {
continue
}
# no version selected: retrieve name
regexp {([^ ]+)\@\@} $line dummy name
set version "Not Selected"
set infoList {}
lappend infoList $version
lappend infoList ""
lappend infoList ""
$infoDict set $name $infoList
continue
}
# if there is no 'Rule' in the line it is not a selected version
if { ![regexp {Rule:} $line] } {
continue
}
# get version path name of file
regexp {^version[ ]+(.*)[ ]+Rule:} $line dummy nameVersion
# get just the path in filePath
regexp {(.*)\@\@} $nameVersion dummy filePath
# get the version name
regexp {\@\@([^ ]+)[ ]+} $nameVersion dummy version
# get the selection rule
regexp {Rule: (.*)$} $line dummy rule
# if file is checkedout append 'from' information
if { [regexp { from [^ ]* } $line fromVersion] } {
set version "$version $fromVersion"
set status "Reserved"
} else {
set status "CheckedIn"
}
set infoList {}
lappend infoList $version
lappend infoList $status
lappend infoList $rule
$infoDict set $filePath $infoList
}
# obtain checkout information
set lscoCommand [CCCommand new "$lscoCommandString" "" "$lscoCommandString"]
if { ![vsCommandHandler executeSilent $lscoCommand] } {
return
}
# if the checkout line contains 'unreserved' retrieve the file name
# and update in dictionary
foreach line [split [$lscoCommand output] "\n"] {
if { [regexp {\(unreserved\)$} $line] } {
regexp { checkout version \"([^"]*)\" } $line dummy filePath
set infoList [$infoDict set $filePath]
$infoDict set $filePath [lreplace $infoList 1 1 "Unreserved"]
}
}
}
# Do a clearcase listing in the directories in
# pathList and return a list with filenames.
#
proc CCCommand::shortListing {pathList} {
set existingPaths {}
foreach path $pathList {
if [file isdirectory $path] {
lappend existingPaths $path
}
}
if [lempty $existingPaths] {
return ""
}
set pathList $existingPaths
set lsCommandString "ls "
foreach path $pathList {
set lsCommandString "$lsCommandString [quoteIf $path]"
}
# execute ClearCase ls commands
set lsCommand [CCCommand new "$lsCommandString" "" "$lsCommandString"]
if { ![vsCommandHandler executeSilent $lsCommand] } {
return ""
}
# retrieve versions only: go through output and select
set fileList {}
foreach line [split [$lsCommand output] "\n"] {
# if there is no 'Rule' in the line it is not a selected version
if { ![regexp {Rule:} $line] } {
continue
}
# get just the path in filePath
regexp {(.*)\@\@} $line dummy filePath
lappend fileList $filePath
}
return $fileList
}
# Do a description on the specified ClearCase object and add to InfoDict:
# Comments, Labels, Attributes, Hyperlinks value pairs.
#
proc CCCommand::describe {path infoDict} {
# First command: retrieve everything but hyperlinks
set commandString "describe -fmt %Na\\n%Vd\\n%u\\n%Nl\\n%c"
set command [CCCommand new "$commandString" "$path" "Retrieving info of $path"]
if { ![vsCommandHandler executeSilent $command] } {
return
}
# parse output and add to the dictionary
set descLines [split [$command output] "\n"]
$infoDict set Attributes [lindex $descLines 0]
$infoDict set Created [lindex $descLines 1]
$infoDict set "Created By" [lindex $descLines 2]
$infoDict set Labels [lindex $descLines 3]
set comments [join [lrange $descLines 4 end] "\n"]
$infoDict set Comments $comments
# Get hyperlinks and ClearCase Type
set commandString "describe"
set command [CCCommand new "$commandString" "$path" "Retrieving description of $path"]
if { ![vsCommandHandler executeSilent $command] } {
return
}
# parse output and retrieve information
# hyperlinks part start with a HyperLinks: line, element type
# is on an element type: line
set inHyperLinkLines 0
set hyperLinkLines {}
set ccType ""
foreach descLine [split [$command output] "\n"] {
if [regexp {element type: (.*)} $descLine dummy type] {
set ccType $type
}
# normally nothing follows the Hyperlinks: part, but be careful
# just in case the comment contains a Hyperlinks: part
if $inHyperLinkLines {
if { ![regexp :$ $descLine] } {
lappend hyperLinkLines $descLine
} else {
set inHyperLinkLines 0
}
}
if [regexp {Hyperlinks:} $descLine] {
set inHyperLinkLines 1
set hyperLinkLines {}
}
}
set hyperLinks [join $hyperLinkLines "\n"]
$infoDict set Hyperlinks [string trim $hyperLinks]
$infoDict set "ClearCase Type" $ccType
# get class that this file was generated from
global VSFile::classAttribute
set name [CCCommand::getAttributeValue $path ${VSFile::classAttribute}]
$infoDict set "Generated From Class" $name
}
# Get the known branch types in the current vob and return them.
#
proc CCCommand::getBranchTypes {vob} {
set command "lstype -brtype -fmt \"%n \" -vob"
set listBranchCommand [CCCommand new "$command" "$vob" "List branch types"]
if { ![vsCommandHandler executeSilent $listBranchCommand] } {
return ""
}
return "[$listBranchCommand output]"
}
# Get the version tree on 'path' and return it.
#
proc CCCommand::getVersions {path} {
set command "lsvtree -all -s -nco"
set lsVersionsCommand [CCCommand new "$command" "$path" "Retrieving versions of $path"]
if { ![vsCommandHandler executeSilent $lsVersionsCommand] } {
return ""
}
# parse output: get version extensions only
# discard versions that are not printable versions such as /main
set versionList {}
foreach outputLine [split [$lsVersionsCommand output] "\n"] {
regsub -all {.*\@\@} $outputLine "" version
if [regexp {.*[0-9]} $version] {
lappend versionList $version
}
}
return $versionList
}
# Get the active views on this machine and return in list.
#
proc CCCommand::getActiveViews {} {
set command "lsview"
set lsViewCommand [CCCommand new "$command" "" "Listing active views"]
if { ![vsCommandHandler executeSilent $lsViewCommand] } {
return ""
}
# parse view list: get active view names only
set viewList {}
foreach outputLine [split [$lsViewCommand output] "\n"] {
if [regexp {\*[ ]+(.*)} $outputLine dummy viewLine] {
regsub {[/A-Z\\].*} $viewLine "" view
lappend viewList [string trim $view]
}
}
return $viewList
}
# Return the clearcase type of this file.
#
proc CCCommand::getClearCaseType {path} {
set commandString "describe"
set command [CCCommand new "$commandString" "$path" "Retrieving description of $path"]
if { ![vsCommandHandler executeSilent $command] } {
return
}
# parse output and retrieve information
# hyperlinks part start with a HyperLinks: line, element type
# is on an element type: line
set ccType ""
foreach descLine [split [$command output] "\n"] {
if [regexp {element type: (.*)} $descLine dummy type] {
set ccType $type
}
}
return $ccType
}
# Returns whether the specified view exists in
# the view directory.
#
proc CCCommand::viewIsActive {view} {
if $win95 {
set viewPath [path_name concat M:\\ $view]
} else {
set viewPath [path_name concat /view $view]
}
return [file isdirectory $viewPath]
}
proc CCCommand::getWorkingView {} {
set command "pwv -s -set"
set pwvCommand [CCCommand new "$command" "" "Determine working view"]
if { ![vsCommandHandler executeSilent $pwvCommand] } {
return ""
}
set view [$pwvCommand output]
if [regexp {\*\* NONE \*\*} $view] {
return ""
}
return $view
}
# Try to start the specified view.
#
proc CCCommand::startView {view} {
set command "startview"
set startViewCommand [CCCommand new "$command" "$view" "Start view $view"]
return [vsCommandHandler execute $startViewCommand]
}
# Get config spec of specified view.
#
proc CCCommand::getConfigSpec {view} {
set command "catcs -tag"
set getConfigSpecCommand [CCCommand new "$command" "$view" "Get config spec of $view"]
if { ![vsCommandHandler executeSilent $getConfigSpecCommand] } {
return ""
}
return [$getConfigSpecCommand output]
}
# Set specified config spec of specified view.
#
proc CCCommand::setConfigSpec {view specFile} {
set command "setcs -tag [quoteIf $view] $specFile"
set setConfigSpecCommand [CCCommand new "$command" "" "Set config spec of $view"]
return [vsCommandHandler execute $setConfigSpecCommand]
}
# Determines the path to cleartool and save it in
# cleartoolPath. Prepend cleartool command.
# Windows only.
#
proc CCCommand::initializeCleartoolPath {} {
global CCCommand::cleartoolPath
global CCCommand::cleartoolCommand
if { ${CCCommand::cleartoolPath} != "" } {
return
}
set fullName [VSCommand::findPath atria cleartool]
if { $fullName != "" } {
set CCCommand::cleartoolPath [path_name directory $fullName]
set CCCommand::cleartoolCommand $fullName
} else {
vsCommandHandler error "cleartool path not found"
}
}
# Returns the version release number of ClearCase.
#
proc CCCommand::getClearCaseVersion {} {
set getVersionCommand [CCCommand new "" "" "Get ClearCase version"]
$getVersionCommand command "${CCCommand::cleartoolCommand} -version"
if { ![vsCommandHandler executeSilent $getVersionCommand] } {
return ""
}
set versionInfo [$getVersionCommand output]
# try to find most relevant version info
if [regexp {ClearCase version ([^ ]+) } $versionInfo dummy version] {
return $version
}
if [regexp {cleartool version ([^ ]+) } $versionInfo dummy version] {
return $version
}
if [regexp { version ([^ ]+) } $versionInfo dummy version] {
return $version
}
return ""
}
# Classify the ClearCase output.
#
method CCCommand::classifyOutput {this} {
set outputLines {}
set warningLines {}
foreach line [split [$this output] "\n"] {
if [regexp -nocase {warning\:} $line] {
lappend warningLines $line
continue
}
lappend outputLines $line
}
if { $warningLines != "" } {
$this warnings [join $warningLines "\n"]
}
$this output [join $outputLines "\n"]
}
# Execute the command and classify if classifyOutput is set.
#
method CCCommand::execute {this {classifyOutput 0}} {
# if there is input feed it to command
if { [$this input] != "" } {
if $win95 {
set echoCommand "cmd.exe /c echo"
} else {
set echoCommand "echo"
}
set commandString "exec $echoCommand [$this input] |"
} else {
set commandString "exec"
}
# do this to keep backslashes
set commandParts [$this command]
while { "$commandParts" != "" } {
if { ![regexp {^"([^"]*)"[ ]*(.*)$} $commandParts \
dummy commandPart commandParts] } {
regexp {^([^ ]*)[ ]*(.*)$} $commandParts \
dummy commandPart commandParts
}
if { "$commandPart" == "" } {
set commandString "$commandString {}"
} else {
if [regexp {\"} $commandPart] {
set commandString "$commandString $commandPart"
} else {
set commandString "$commandString [list $commandPart]"
}
}
}
# do it
if [ catch { set output [eval $commandString] } errors] {
# Remove cleartool strings from output
regsub -all {cleartool[^:]*: } $errors "" commandOutput
# Cleartool has error exit status on warnings so check
# if this really was an error
if { ![regexp -nocase {warning:} $commandOutput] } {
$this errors $commandOutput
$this removeTempFiles
return
}
} else {
# Remove cleartool strings
regsub -all {cleartool[^:]*: } $output "" commandOutput
}
$this output $commandOutput
if $classifyOutput {
$this classifyOutput
}
$this removeTempFiles
}
# Do not delete this line -- regeneration end marker