File Annotation
Not logged in
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