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. 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: } d8c18fc148 2007-09-17 aku: return d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 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]]] 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: # OLD api calls ... TODO rework for more structure ... d8c18fc148 2007-09-17 aku: csets ; # Group changes into sets 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 d8c18fc148 2007-09-17 aku: return d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 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 ncs 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: d8c18fc148 2007-09-17 aku: return $ncs 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} { d8c18fc148 2007-09-17 aku: variable workspace ; cd $workspace d8c18fc148 2007-09-17 aku: wssetup $id ; # OLD api ... TODO inline d8c18fc148 2007-09-17 aku: } d8c18fc148 2007-09-17 aku: d8c18fc148 2007-09-17 aku: # ----------------------------------------------------------------------------- d8c18fc148 2007-09-17 aku: # Internals - Old API for now. d8c18fc148 2007-09-17 aku: 1593006ef3 2007-09-17 aku: proc ::vc::cvs::ws::DefBase {path} { 1593006ef3 2007-09-17 aku: variable project 1593006ef3 2007-09-17 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 {} { 1593006ef3 2007-09-17 aku: variable project 1593006ef3 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: } df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Scan repository, collect archives, parse them, and collect revision df91d389d5 2007-09-04 aku: # information (file, revision -> date, author, commit message) df91d389d5 2007-09-04 aku: 1593006ef3 2007-09-17 aku: proc ::vc::cvs::ws::ScanArchives {files} { 6f121db1e2 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 {} 1593006ef3 2007-09-17 aku: set n 0 6f121db1e2 2007-09-17 aku: 6f121db1e2 2007-09-17 aku: ::foreach {rcs f} $files { 6f121db1e2 2007-09-17 aku: write 1 cvs "Archive $rcs" 6f121db1e2 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) 1593006ef3 2007-09-17 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 df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 1593006ef3 2007-09-17 aku: write 0 cvs "Generated [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: } 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::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: 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 2740b48b63 2007-09-17 aku: } 1593006ef3 2007-09-17 aku: df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Group single changes into changesets df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: proc ::vc::cvs::ws::csets {} { df91d389d5 2007-09-04 aku: variable timeline df91d389d5 2007-09-04 aku: variable csets df91d389d5 2007-09-04 aku: variable ncs df91d389d5 2007-09-04 aku: variable cmap df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: array unset csets * ; array set csets {} df91d389d5 2007-09-04 aku: array unset cmap * ; array set cmap {} df91d389d5 2007-09-04 aku: set ncs 0 df91d389d5 2007-09-04 aku: 1593006ef3 2007-09-17 aku: write 0 cvs "Generating changesets from timeline" 1593006ef3 2007-09-17 aku: df91d389d5 2007-09-04 aku: CSClear 1593006ef3 2007-09-17 aku: timeline::foreach date file revision operation author cmsg { 1593006ef3 2007-09-17 aku: # API adaption 1593006ef3 2007-09-17 aku: set entry [list $operation $date $author $revision $file $cmsg] 1593006ef3 2007-09-17 aku: 1593006ef3 2007-09-17 aku: if {![CSNone] && [CSNew $entry]} { 1593006ef3 2007-09-17 aku: CSSave 1593006ef3 2007-09-17 aku: CSClear df91d389d5 2007-09-04 aku: } 1593006ef3 2007-09-17 aku: CSAdd $entry df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 1593006ef3 2007-09-17 aku: write 0 cvs "Found [NSIPL [array size csets] changeset]" df91d389d5 2007-09-04 aku: return df91d389d5 2007-09-04 aku: } 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: # Changeset data: df91d389d5 2007-09-04 aku: # ncs: Counter-based id generation df91d389d5 2007-09-04 aku: # csets: id -> (user commit start end depth (file -> (op rev))) df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: variable ncs ; set ncs 0 ; # Counter for changesets df91d389d5 2007-09-04 aku: variable csets ; array set csets {} ; # Changeset data 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 csets 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: d8c18fc148 2007-09-17 aku: ::foreach c [lrange [lsort -integer [array names csets]] 1 end] { d8c18fc148 2007-09-17 aku: ::foreach {u cm s e rd f} $csets($c) break df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Ignore branch changes, just count them for the statistics. df91d389d5 2007-09-04 aku: if {$rd != 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::wssetup {c} { df91d389d5 2007-09-04 aku: variable csets df91d389d5 2007-09-04 aku: variable base d8c18fc148 2007-09-17 aku: variable project df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # pwd = workspace df91d389d5 2007-09-04 aku: d8c18fc148 2007-09-17 aku: ::foreach {u cm s e rd fs} $csets($c) break be32ebcb41 2007-09-08 aku: be32ebcb41 2007-09-08 aku: write 1 cvs "@ $s" be32ebcb41 2007-09-08 aku: d8c18fc148 2007-09-17 aku: ::foreach l [split [string trim $cm] \n] { be32ebcb41 2007-09-08 aku: write 1 cvs "| $l" df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: d8c18fc148 2007-09-17 aku: ::foreach {f or} $fs { d8c18fc148 2007-09-17 aku: ::foreach {op r} $or break be32ebcb41 2007-09-08 aku: write 2 cvs "$op $f $r" df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: if {$op eq "R"} { df91d389d5 2007-09-04 aku: # Remove file from workspace. Prune empty directories. df91d389d5 2007-09-04 aku: # df91d389d5 2007-09-04 aku: # NOTE: A dead-first file (rev 1.1 dead) will never have df91d389d5 2007-09-04 aku: # existed. df91d389d5 2007-09-04 aku: # df91d389d5 2007-09-04 aku: # NOTE: Logically empty directories still physically df91d389d5 2007-09-04 aku: # contain the CVS admin directory, hence the check for == df91d389d5 2007-09-04 aku: # 1, not == 0. There might also be hidden files, we count df91d389d5 2007-09-04 aku: # them as well. Always hidden are . and .. and they do not df91d389d5 2007-09-04 aku: # count as user file. df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: file delete $f df91d389d5 2007-09-04 aku: set fd [file dirname $f] df91d389d5 2007-09-04 aku: if { df91d389d5 2007-09-04 aku: ([llength [glob -nocomplain -directory $fd *]] == 1) && df91d389d5 2007-09-04 aku: ([llength [glob -nocomplain -directory -type hidden $fd *]] == 2) df91d389d5 2007-09-04 aku: } { df91d389d5 2007-09-04 aku: file delete -force $fd df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: } else { df91d389d5 2007-09-04 aku: # Added or modified, put the requested version of the file df91d389d5 2007-09-04 aku: # into the workspace. df91d389d5 2007-09-04 aku: d8c18fc148 2007-09-17 aku: if {$project ne ""} {set f $project/$f} df91d389d5 2007-09-04 aku: if {[catch { cdf5e6d8b7 2007-09-13 aku: dova -d $base co -r $r $f df91d389d5 2007-09-04 aku: } msg]} { df91d389d5 2007-09-04 aku: if {[string match {*invalid change text*} $msg]} { df91d389d5 2007-09-04 aku: # The archive of the file is corrupted and the df91d389d5 2007-09-04 aku: # chosen version not accessible due to that. We df91d389d5 2007-09-04 aku: # report the problem, but otherwise ignore it. As d8c18fc148 2007-09-17 aku: # a consequence the destination repository will not df91d389d5 2007-09-04 aku: # contain the full history of the named file. By df91d389d5 2007-09-04 aku: # ignoring the problem we however get as much as df91d389d5 2007-09-04 aku: # is possible. df91d389d5 2007-09-04 aku: be32ebcb41 2007-09-08 aku: write 0 cvs "EE Corrupted archive file. Inaccessible revision." df91d389d5 2007-09-04 aku: continue df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: return -code error $msg df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Provide metadata about the changeset the backend may wish to have b504674c5f 2007-09-15 aku: return [list $u $s $cm] df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: proc ::vc::cvs::ws::foreach_cset {cv node script} { df91d389d5 2007-09-04 aku: upvar 1 $cv c df91d389d5 2007-09-04 aku: variable rtree df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: set c $node df91d389d5 2007-09-04 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 8469631cc9 2007-09-08 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: df91d389d5 2007-09-04 aku: # ----------------------------------------------------------------------------- df91d389d5 2007-09-04 aku: # Internal helper commands: Changeset inspection and construction. df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: proc ::vc::cvs::ws::CSClear {} { df91d389d5 2007-09-04 aku: upvar 1 start start end end cm cm user user files files lastd lastd df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: set start {} df91d389d5 2007-09-04 aku: set end {} df91d389d5 2007-09-04 aku: set cm {} df91d389d5 2007-09-04 aku: set user {} df91d389d5 2007-09-04 aku: set lastd {} df91d389d5 2007-09-04 aku: array unset files * df91d389d5 2007-09-04 aku: array set files {} df91d389d5 2007-09-04 aku: return df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: proc ::vc::cvs::ws::CSNone {} { df91d389d5 2007-09-04 aku: upvar 1 start start df91d389d5 2007-09-04 aku: return [expr {$start eq ""}] df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: proc ::vc::cvs::ws::CSNew {entry} { df91d389d5 2007-09-04 aku: upvar 1 start start end end cm cm user user files files lastd lastd reason reason df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: #puts -nonewline stdout . ; flush stdout df91d389d5 2007-09-04 aku: d8c18fc148 2007-09-17 aku: ::foreach {op ts a rev f ecm} $entry break df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # User change df91d389d5 2007-09-04 aku: if {$a ne $user} {set reason user ; return 1} df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # File already in current cset df91d389d5 2007-09-04 aku: if {[info exists files($f)]} {set reason file ; return 1} df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Current cset trunk/branch different from entry. df91d389d5 2007-09-04 aku: set depth [llength [split $rev .]] df91d389d5 2007-09-04 aku: if {($lastd == 2) != ($depth == 2)} {set reason depth/$lastd/$depth/($rev)/$f ; return 1} df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Commit message changed df91d389d5 2007-09-04 aku: if {$cm ne $ecm} {set reason cmsg\ <<$ecm>> ; return 1} df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Everything is good, still the same cset df91d389d5 2007-09-04 aku: return 0 df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: proc ::vc::cvs::ws::CSSave {} { df91d389d5 2007-09-04 aku: variable cmap df91d389d5 2007-09-04 aku: variable csets df91d389d5 2007-09-04 aku: variable ncs df91d389d5 2007-09-04 aku: upvar 1 start start end end cm cm user user files files lastd lastd df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: set csets($ncs) [list $user $cm $start $end $lastd [array get files]] df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Record which revisions of a file are in what csets d8c18fc148 2007-09-17 aku: ::foreach {f or} [array get files] { d8c18fc148 2007-09-17 aku: ::foreach {_ rev} $or break df91d389d5 2007-09-04 aku: set cmap([list $f $rev]) $ncs df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: #CSDump $ncs df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: incr ncs df91d389d5 2007-09-04 aku: return df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: proc ::vc::cvs::ws::CSAdd {entry} { df91d389d5 2007-09-04 aku: upvar 1 start start end end cm cm user user files files lastd lastd df91d389d5 2007-09-04 aku: d8c18fc148 2007-09-17 aku: ::foreach {op ts a rev f ecm} $entry break df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: if {$start eq ""} {set start $ts} df91d389d5 2007-09-04 aku: set end $ts df91d389d5 2007-09-04 aku: set cm $ecm df91d389d5 2007-09-04 aku: set user $a df91d389d5 2007-09-04 aku: set files($f) [list $op $rev] df91d389d5 2007-09-04 aku: set lastd [llength [split $rev .]] df91d389d5 2007-09-04 aku: return df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: 00228d1547 2007-09-13 aku: proc ::vc::cvs::ws::CSDump {c} { df91d389d5 2007-09-04 aku: variable csets d8c18fc148 2007-09-17 aku: ::foreach {u cm s e rd f} $csets($c) break df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: puts "$u $s"; regsub -all {.} $u { } b df91d389d5 2007-09-04 aku: puts "$b $e" d8c18fc148 2007-09-17 aku: ::foreach {f or} $f { d8c18fc148 2007-09-17 aku: ::foreach {o r} $or break df91d389d5 2007-09-04 aku: puts "$b $o $f $r" df91d389d5 2007-09-04 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]" 1593006ef3 2007-09-17 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: # ----------------------------------------------------------------------------- d8c18fc148 2007-09-17 aku: 00228d1547 2007-09-13 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: df91d389d5 2007-09-04 aku: # ----------------------------------------------------------------------------- df91d389d5 2007-09-04 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