df91d389d5 2007-09-04 aku: # ----------------------------------------------------------------------------- df91d389d5 2007-09-04 aku: # Repository management (CVS) df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # ----------------------------------------------------------------------------- df91d389d5 2007-09-04 aku: # Requirements df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: package require Tcl 8.4 1593006ef3 2007-09-17 aku: package require fileutil ; # Tcllib (traverse directory hierarchy) 1593006ef3 2007-09-17 aku: package require vc::rcs::parser ; # Handling the RCS archive files. 1593006ef3 2007-09-17 aku: package require vc::tools::log ; # User feedback 1593006ef3 2007-09-17 aku: package require vc::cvs::cmd ; # Access to cvs application. 1593006ef3 2007-09-17 aku: package require vc::cvs::ws::files ; # Scan CVS repository for relevant files. 1593006ef3 2007-09-17 aku: package require vc::cvs::ws::timeline ; # Manage timeline of all changes. ae54e928c2 2007-09-17 aku: package require vc::cvs::ws::csets ; # Manage the changesets found in the timeline df91d389d5 2007-09-04 aku: package require struct::tree df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: namespace eval ::vc::cvs::ws { 86a7f249c1 2007-09-09 aku: vc::tools::log::system cvs 86a7f249c1 2007-09-09 aku: namespace import ::vc::tools::log::write d4aa7da67d 2007-09-13 aku: namespace import ::vc::rcs::parser::process cdf5e6d8b7 2007-09-13 aku: namespace import ::vc::cvs::cmd::dova be32ebcb41 2007-09-08 aku: } df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # ----------------------------------------------------------------------------- df91d389d5 2007-09-04 aku: # API df91d389d5 2007-09-04 aku: d8c18fc148 2007-09-17 aku: # vc::cvs::ws::configure key value - Configure the subsystem. d8c18fc148 2007-09-17 aku: # vc::cvs::ws::check src mv - Check if src is a CVS repository directory. d8c18fc148 2007-09-17 aku: # vc::cvs::ws::begin src - Start new workspace and return the top- d8c18fc148 2007-09-17 aku: # most directory co'd files are put into. d8c18fc148 2007-09-17 aku: # vc::cvs::ws::ncsets ?-import? - Retrieve number of csets (all/to import) d8c18fc148 2007-09-17 aku: # vc::cvs::ws::foreach csvar script - Run the script for each changeset, the d8c18fc148 2007-09-17 aku: # id of the current changeset stored in d8c18fc148 2007-09-17 aku: # the variable named by csvar. d8c18fc148 2007-09-17 aku: # vc::cvs::ws::done - Close workspace and delete it. d8c18fc148 2007-09-17 aku: # vc::cvs::ws::isadmin path - Check if path is an admin file of CVS d8c18fc148 2007-09-17 aku: # vc::cvs::ws::checkout id - Have workspace contain the changeset id. d8c18fc148 2007-09-17 aku: # d8c18fc148 2007-09-17 aku: # Configuration keys: d8c18fc148 2007-09-17 aku: # d8c18fc148 2007-09-17 aku: # -project path - Sub directory under 'src' to limit the import to. d8c18fc148 2007-09-17 aku: d8c18fc148 2007-09-17 aku: # ----------------------------------------------------------------------------- d8c18fc148 2007-09-17 aku: # API Implementation d8c18fc148 2007-09-17 aku: d8c18fc148 2007-09-17 aku: proc ::vc::cvs::ws::configure {key value} { d8c18fc148 2007-09-17 aku: variable project d8c18fc148 2007-09-17 aku: d8c18fc148 2007-09-17 aku: switch -exact -- $key { d8c18fc148 2007-09-17 aku: -project { set project $value } d8c18fc148 2007-09-17 aku: default { d8c18fc148 2007-09-17 aku: return -code error "Unknown switch $key, expected \ d8c18fc148 2007-09-17 aku: -project" d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 aku: } df91d389d5 2007-09-04 aku: return df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: d8c18fc148 2007-09-17 aku: proc ::vc::cvs::ws::check {src mv} { d8c18fc148 2007-09-17 aku: variable project d8c18fc148 2007-09-17 aku: upvar 1 $mv msg d8c18fc148 2007-09-17 aku: if { d8c18fc148 2007-09-17 aku: ![fileutil::test $src erd msg "CVS Repository"] || d8c18fc148 2007-09-17 aku: ![fileutil::test $src/CVSROOT erd msg "CVS Admin directory"] || d8c18fc148 2007-09-17 aku: (($project ne "") && d8c18fc148 2007-09-17 aku: ![fileutil::test $src/$project erd msg "Project directory"]) d8c18fc148 2007-09-17 aku: } { d8c18fc148 2007-09-17 aku: return 0 d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 aku: return 1 d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 aku: d8c18fc148 2007-09-17 aku: proc ::vc::cvs::ws::begin {src} { 1593006ef3 2007-09-17 aku: if {![check $src msg]} { return -code error $msg } 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: DefBase $src 1593006ef3 2007-09-17 aku: MakeTimeline [ScanArchives [files::find [RootPath]]] ae54e928c2 2007-09-17 aku: MakeChangesets d8c18fc148 2007-09-17 aku: d8c18fc148 2007-09-17 aku: # OLD api calls ... TODO rework for more structure ... d8c18fc148 2007-09-17 aku: rtree ; # Build revision tree (trunk only right now). d8c18fc148 2007-09-17 aku: 2740b48b63 2007-09-17 aku: return [MakeWorkspace] d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 aku: d8c18fc148 2007-09-17 aku: proc ::vc::cvs::ws::done {} { 2740b48b63 2007-09-17 aku: variable workspace d8c18fc148 2007-09-17 aku: file delete -force $workspace df91d389d5 2007-09-04 aku: return df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: d8c18fc148 2007-09-17 aku: proc ::vc::cvs::ws::foreach {cv script} { d8c18fc148 2007-09-17 aku: # OLD api ... TODO inline d8c18fc148 2007-09-17 aku: uplevel 1 [list ::vc::cvs::ws::foreach_cset $cv 0 $script] d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 aku: d8c18fc148 2007-09-17 aku: proc ::vc::cvs::ws::ncsets {args} { d8c18fc148 2007-09-17 aku: variable ntrunk d8c18fc148 2007-09-17 aku: d8c18fc148 2007-09-17 aku: if {[llength $args] > 1} { d8c18fc148 2007-09-17 aku: return -code error "wrong#args: Expected ?-import?" d8c18fc148 2007-09-17 aku: } elseif {[llength $args] == 1} { d8c18fc148 2007-09-17 aku: if {[set k [lindex $args 0]] ne "-import"} { d8c18fc148 2007-09-17 aku: return -code "Unknown switch $k, expected -import" d8c18fc148 2007-09-17 aku: } else { d8c18fc148 2007-09-17 aku: return $ntrunk d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 aku: ae54e928c2 2007-09-17 aku: return [csets::num] d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 aku: d8c18fc148 2007-09-17 aku: proc ::vc::cvs::ws::isadmin {path} { d8c18fc148 2007-09-17 aku: # Check if path is a CVS admin file. d8c18fc148 2007-09-17 aku: if {[string match CVS/* $path]} {return 1} d8c18fc148 2007-09-17 aku: if {[string match */CVS/* $path]} {return 1} d8c18fc148 2007-09-17 aku: return 0 d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 aku: d8c18fc148 2007-09-17 aku: proc ::vc::cvs::ws::checkout {id} { ae54e928c2 2007-09-17 aku: variable workspace ae54e928c2 2007-09-17 aku: cd $workspace ae54e928c2 2007-09-17 aku: ae54e928c2 2007-09-17 aku: array set cs [csets::get $id] ae54e928c2 2007-09-17 aku: ae54e928c2 2007-09-17 aku: write 1 cvs "@ $cs(date)" ae54e928c2 2007-09-17 aku: ::foreach l [split [string trim $cs(cmsg)] \n] { ae54e928c2 2007-09-17 aku: write 1 cvs "| $l" ae54e928c2 2007-09-17 aku: } ae54e928c2 2007-09-17 aku: ae54e928c2 2007-09-17 aku: ::foreach {f r} $cs(removed) { write 2 cvs "R $f $r" ; Remove $f $r } ae54e928c2 2007-09-17 aku: ::foreach {f r} $cs(added) { write 2 cvs "A $f $r" ; Checkout $f $r } ae54e928c2 2007-09-17 aku: ::foreach {f r} $cs(changed) { write 2 cvs "M $f $r" ; Checkout $f $r } ae54e928c2 2007-09-17 aku: ae54e928c2 2007-09-17 aku: # Provide metadata about the changeset the backend may wish to have ae54e928c2 2007-09-17 aku: return [list $cs(author) $cs(date) $cs(cmsg)] d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 aku: d8c18fc148 2007-09-17 aku: # ----------------------------------------------------------------------------- ae54e928c2 2007-09-17 aku: # Internals 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: proc ::vc::cvs::ws::DefBase {path} { 6f121db1e2 2007-09-17 aku: variable project df91d389d5 2007-09-04 aku: variable base 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: set base $path 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: write 0 cvs "Base: $base" 1593006ef3 2007-09-17 aku: if {$project eq ""} { 1593006ef3 2007-09-17 aku: write 0 cvs "Project: <ALL>" 1593006ef3 2007-09-17 aku: } else { 1593006ef3 2007-09-17 aku: write 0 cvs "Project: $project" 1593006ef3 2007-09-17 aku: } df91d389d5 2007-09-04 aku: return df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 1593006ef3 2007-09-17 aku: proc ::vc::cvs::ws::RootPath {} { d8c18fc148 2007-09-17 aku: variable project d8c18fc148 2007-09-17 aku: variable base 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: if {$project eq ""} { 1593006ef3 2007-09-17 aku: return $base 1593006ef3 2007-09-17 aku: } else { 1593006ef3 2007-09-17 aku: return $base/$project 1593006ef3 2007-09-17 aku: } 1593006ef3 2007-09-17 aku: } 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: proc ::vc::cvs::ws::ScanArchives {files} { 1593006ef3 2007-09-17 aku: write 0 cvs "Scanning archives ..." 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: set d [RootPath] 1593006ef3 2007-09-17 aku: set r {} d8c18fc148 2007-09-17 aku: set n 0 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: ::foreach {rcs f} $files { d8c18fc148 2007-09-17 aku: write 1 cvs "Archive $rcs" d8c18fc148 2007-09-17 aku: # Get the meta data we need (revisions, timeline, messages). 1593006ef3 2007-09-17 aku: lappend r $f [process $d/$rcs] 1593006ef3 2007-09-17 aku: incr n 1593006ef3 2007-09-17 aku: } 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: write 0 cvs "Processed [NSIPL $n file]" 1593006ef3 2007-09-17 aku: return $r 1593006ef3 2007-09-17 aku: } 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: proc ::vc::cvs::ws::MakeTimeline {meta} { 1593006ef3 2007-09-17 aku: write 0 cvs "Generating coalesced timeline ..." df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: set n 0 1593006ef3 2007-09-17 aku: ::foreach {f meta} $meta { 1593006ef3 2007-09-17 aku: array set md $meta 1593006ef3 2007-09-17 aku: array set date $md(date) 1593006ef3 2007-09-17 aku: array set auth $md(author) 1593006ef3 2007-09-17 aku: array set cmsg $md(commit) 1593006ef3 2007-09-17 aku: array set stat $md(state) 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: ::foreach rev [lsort -dict [array names date]] { 1593006ef3 2007-09-17 aku: set operation [Operation $rev $stat($rev)] 1593006ef3 2007-09-17 aku: NoteDeadRoots $f $rev $operation 1593006ef3 2007-09-17 aku: timeline::add $date($rev) $f $rev $operation $auth($rev) $cmsg($rev) df91d389d5 2007-09-04 aku: incr n df91d389d5 2007-09-04 aku: } 1593006ef3 2007-09-17 aku: #B Extend branch management 10e3b3ed76 2007-09-17 aku: 10e3b3ed76 2007-09-17 aku: unset md 10e3b3ed76 2007-09-17 aku: unset date 10e3b3ed76 2007-09-17 aku: unset auth 10e3b3ed76 2007-09-17 aku: unset cmsg 10e3b3ed76 2007-09-17 aku: unset stat 1593006ef3 2007-09-17 aku: } 1593006ef3 2007-09-17 aku: ae54e928c2 2007-09-17 aku: write 0 cvs "Timeline has [NSIPL $n entry entries]" 1593006ef3 2007-09-17 aku: return 1593006ef3 2007-09-17 aku: } 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: proc ::vc::cvs::ws::NoteDeadRoots {f rev operation} { 1593006ef3 2007-09-17 aku: # A dead-first revision is rev 1.1 with op R. For an example see 1593006ef3 2007-09-17 aku: # the file memchan/DEPENDENCIES. Such a file seems to exist only! 1593006ef3 2007-09-17 aku: # on its branch. The branches information is set on the revision 1593006ef3 2007-09-17 aku: # (extend rcsparser!), symbols has a tag, refering to a branch, 1593006ef3 2007-09-17 aku: # possibly magic. 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: if {($rev eq "1.1") && ($operation eq "R")} { 1593006ef3 2007-09-17 aku: write 2 cvs "Dead root revision: $f" 1593006ef3 2007-09-17 aku: } 1593006ef3 2007-09-17 aku: return 1593006ef3 2007-09-17 aku: } 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: proc ::vc::cvs::ws::Operation {rev state} { 1593006ef3 2007-09-17 aku: if {$state eq "dead"} {return "R"} ; # Removed 1593006ef3 2007-09-17 aku: if {$rev eq "1.1"} {return "A"} ; # Added 1593006ef3 2007-09-17 aku: return "M" ; # Modified 1593006ef3 2007-09-17 aku: } 1593006ef3 2007-09-17 aku: ae54e928c2 2007-09-17 aku: proc ::vc::cvs::ws::MakeChangesets {} { 1593006ef3 2007-09-17 aku: write 0 cvs "Generating changesets from timeline" 1593006ef3 2007-09-17 aku: ae54e928c2 2007-09-17 aku: csets::init 1593006ef3 2007-09-17 aku: timeline::foreach date file revision operation author cmsg { ae54e928c2 2007-09-17 aku: csets::add $date $file $revision $operation $author $cmsg df91d389d5 2007-09-04 aku: } ae54e928c2 2007-09-17 aku: csets::done ae54e928c2 2007-09-17 aku: ae54e928c2 2007-09-17 aku: write 0 cvs "Found [NSIPL [csets::num] changeset]" df91d389d5 2007-09-04 aku: return df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 2740b48b63 2007-09-17 aku: proc ::vc::cvs::ws::MakeWorkspace {} { 2740b48b63 2007-09-17 aku: variable project 2740b48b63 2007-09-17 aku: variable workspace [fileutil::tempfile importF_cvs_ws_] 2740b48b63 2007-09-17 aku: 2740b48b63 2007-09-17 aku: set w $workspace 2740b48b63 2007-09-17 aku: if {$project ne ""} { append w /$project } 2740b48b63 2007-09-17 aku: 2740b48b63 2007-09-17 aku: file delete $workspace 2740b48b63 2007-09-17 aku: file mkdir $w 2740b48b63 2007-09-17 aku: 2740b48b63 2007-09-17 aku: write 0 cvs "Workspace: $workspace" 2740b48b63 2007-09-17 aku: return $w df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Building the revision tree from the changesets. df91d389d5 2007-09-04 aku: # Limitation: Currently only trunk csets is handled. df91d389d5 2007-09-04 aku: # Limitation: Dead files are not removed, i.e. no 'R' actions right now. df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: proc ::vc::cvs::ws::rtree {} { df91d389d5 2007-09-04 aku: variable rtree {} df91d389d5 2007-09-04 aku: variable ntrunk 0 df91d389d5 2007-09-04 aku: be32ebcb41 2007-09-08 aku: write 0 cvs "Extracting the trunk" be32ebcb41 2007-09-08 aku: 00228d1547 2007-09-13 aku: set rtree [struct::tree ::vc::cvs::ws::RT] df91d389d5 2007-09-04 aku: $rtree rename root 0 ; # Root is first changeset, always. df91d389d5 2007-09-04 aku: set trunk 0 df91d389d5 2007-09-04 aku: set ntrunk 1 ; # Root is on the trunk. df91d389d5 2007-09-04 aku: set b 0 ; # No branch csets found yet. df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Extracting the trunk is easy, simply by looking at the involved df91d389d5 2007-09-04 aku: # version numbers. df91d389d5 2007-09-04 aku: ae54e928c2 2007-09-17 aku: for {set c 1} {$c < [csets::num]} {incr c} { ae54e928c2 2007-09-17 aku: array set cs [csets::get $c] df91d389d5 2007-09-04 aku: # Ignore branch changes, just count them for the statistics. ae54e928c2 2007-09-17 aku: if {$cs(lastd) != 2} { df91d389d5 2007-09-04 aku: incr b df91d389d5 2007-09-04 aku: continue df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Trunk revision, connect to, and update the head. df91d389d5 2007-09-04 aku: $rtree insert $trunk end $c df91d389d5 2007-09-04 aku: set trunk $c df91d389d5 2007-09-04 aku: incr ntrunk df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: be32ebcb41 2007-09-08 aku: write 0 cvs "Processed $ntrunk trunk [expr {($ntrunk == 1) ? "changeset" : "changesets"}]" be32ebcb41 2007-09-08 aku: write 0 cvs "Ignored $b branch [expr {($b == 1) ? "changeset" : "changesets"}]" df91d389d5 2007-09-04 aku: return df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: namespace eval ::vc::cvs::ws { df91d389d5 2007-09-04 aku: # Tree holding trunk and branch information (struct::tree). df91d389d5 2007-09-04 aku: # Node names are cset id's. df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: variable rtree {} df91d389d5 2007-09-04 aku: variable ntrunk 0 df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: proc ::vc::cvs::ws::foreach_cset {cv node script} { 8469631cc9 2007-09-08 aku: upvar 1 $cv c 8469631cc9 2007-09-08 aku: variable rtree 8469631cc9 2007-09-08 aku: 8469631cc9 2007-09-08 aku: set c $node 8469631cc9 2007-09-08 aku: while {1} { 8469631cc9 2007-09-08 aku: set code [catch {uplevel 1 $script} res] 8469631cc9 2007-09-08 aku: 8469631cc9 2007-09-08 aku: # 0 - ok, 1 - error, 2 - return, 3 - break, 4 - continue 8469631cc9 2007-09-08 aku: switch -- $code { 8469631cc9 2007-09-08 aku: 0 {} be32ebcb41 2007-09-08 aku: 1 { return -errorcode $::errorCode -errorinfo $::errorInfo -code error $res } 8469631cc9 2007-09-08 aku: 2 {} 8469631cc9 2007-09-08 aku: 3 { return } 8469631cc9 2007-09-08 aku: 4 {} 8469631cc9 2007-09-08 aku: default { 8469631cc9 2007-09-08 aku: return -code $code $result df91d389d5 2007-09-04 aku: } 8469631cc9 2007-09-08 aku: } df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Stop on reaching the head. df91d389d5 2007-09-04 aku: if {![llength [$rtree children $c]]} break df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: #puts <[$rtree children $c]> df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Go to next child in trunk (leftmost). df91d389d5 2007-09-04 aku: set c [lindex [$rtree children $c] 0] df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: return df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: ae54e928c2 2007-09-17 aku: proc ::vc::cvs::ws::Checkout {f r} { ae54e928c2 2007-09-17 aku: variable base ae54e928c2 2007-09-17 aku: variable project ae54e928c2 2007-09-17 aku: ae54e928c2 2007-09-17 aku: # Added or modified, put the requested version of the file into ae54e928c2 2007-09-17 aku: # the workspace. ae54e928c2 2007-09-17 aku: ae54e928c2 2007-09-17 aku: if {$project ne ""} {set f $project/$f} ae54e928c2 2007-09-17 aku: if {[catch { ae54e928c2 2007-09-17 aku: dova -d $base co -r $r $f ae54e928c2 2007-09-17 aku: } msg]} { ae54e928c2 2007-09-17 aku: if {[string match {*invalid change text*} $msg]} { ae54e928c2 2007-09-17 aku: ae54e928c2 2007-09-17 aku: # The archive of the file is corrupted and the chosen ae54e928c2 2007-09-17 aku: # version not accessible due to that. We report the ae54e928c2 2007-09-17 aku: # problem, but otherwise ignore it. As a consequence the ae54e928c2 2007-09-17 aku: # destination repository will not contain the full history ae54e928c2 2007-09-17 aku: # of the named file. By ignoring the problem we however ae54e928c2 2007-09-17 aku: # get as much as is possible. df91d389d5 2007-09-04 aku: ae54e928c2 2007-09-17 aku: write 0 cvs "EE Corrupted archive file. Inaccessible revision." ae54e928c2 2007-09-17 aku: return ae54e928c2 2007-09-17 aku: } ae54e928c2 2007-09-17 aku: return -code error $msg ae54e928c2 2007-09-17 aku: } 1593006ef3 2007-09-17 aku: return df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: ae54e928c2 2007-09-17 aku: proc ::vc::cvs::ws::Remove {f r} { ae54e928c2 2007-09-17 aku: # Remove file from workspace. Prune empty directories. ae54e928c2 2007-09-17 aku: # NOTE: A dead-first file (rev 1.1 dead) will never have existed. be32ebcb41 2007-09-08 aku: ae54e928c2 2007-09-17 aku: file delete $f ae54e928c2 2007-09-17 aku: Prune [file dirname $f] df91d389d5 2007-09-04 aku: return df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: ae54e928c2 2007-09-17 aku: proc ::vc::cvs::ws::Prune {path} { ae54e928c2 2007-09-17 aku: # NOTE: Logically empty directories still physically contain the ae54e928c2 2007-09-17 aku: # CVS admin directory, hence the check for == 1, not == 0. There ae54e928c2 2007-09-17 aku: # might also be hidden files, we count them as well. Always hidden ae54e928c2 2007-09-17 aku: # are . and .. and they do not count as user file. df91d389d5 2007-09-04 aku: ae54e928c2 2007-09-17 aku: if { ae54e928c2 2007-09-17 aku: ([llength [glob -nocomplain -directory $path *]] == 1) && ae54e928c2 2007-09-17 aku: ([llength [glob -nocomplain -directory -type hidden $path *]] == 2) ae54e928c2 2007-09-17 aku: } { ae54e928c2 2007-09-17 aku: file delete -force $path 1593006ef3 2007-09-17 aku: } df91d389d5 2007-09-04 aku: return df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 1593006ef3 2007-09-17 aku: proc ::vc::cvs::ws::NSIPL {n singular {plural {}}} { 1593006ef3 2007-09-17 aku: return "$n [SIPL $n $singular $plural]" 00228d1547 2007-09-13 aku: } 1593006ef3 2007-09-17 aku: proc ::vc::cvs::ws::SIPL {n singular {plural {}}} { 1593006ef3 2007-09-17 aku: if {$n == 1} {return $singular} 1593006ef3 2007-09-17 aku: if {$plural eq ""} {set plural ${singular}s} 1593006ef3 2007-09-17 aku: return $plural df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: d8c18fc148 2007-09-17 aku: # ----------------------------------------------------------------------------- df91d389d5 2007-09-04 aku: d8c18fc148 2007-09-17 aku: namespace eval ::vc::cvs::ws { 2740b48b63 2007-09-17 aku: variable base {} ; # Toplevel repository directory 2740b48b63 2007-09-17 aku: variable project {} ; # Sub directory to limit the import to. 2740b48b63 2007-09-17 aku: variable workspace {} ; # Directory to checkout changesets to. df91d389d5 2007-09-04 aku: d8c18fc148 2007-09-17 aku: namespace export configure begin done foreach ncsets checkout df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: # ----------------------------------------------------------------------------- 00228d1547 2007-09-13 aku: # Ready df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: package provide vc::cvs::ws 1.0 df91d389d5 2007-09-04 aku: return