f166b0a63c 2007-08-31 aku: #!/bin/sh f166b0a63c 2007-08-31 aku: # -*- tcl -*- \ f166b0a63c 2007-08-31 aku: exec tclsh "$0" ${1+"$@"} f166b0a63c 2007-08-31 aku: f166b0a63c 2007-08-31 aku: # ----------------------------------------------------------------------------- df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Import the trunk of a CVS repository wholesale into a fossil repository. df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # Limitations implicitly mentioned: df91d389d5 2007-09-04 aku: # - No incremental import. df91d389d5 2007-09-04 aku: # - No import of branches. df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # WIBNI features (beyond eliminating the limitations): df91d389d5 2007-09-04 aku: # - Restrict import to specific directory subtrees (SF projects use df91d389d5 2007-09-04 aku: # one repository for several independent modules. Examples: tcllib df91d389d5 2007-09-04 aku: # -> tcllib, tklib, tclapps, etc.). The restriction would allow import df91d389d5 2007-09-04 aku: # of only a specific module. df91d389d5 2007-09-04 aku: # - Related to the previous, strip elements from the base path to keep df91d389d5 2007-09-04 aku: # it short. df91d389d5 2007-09-04 aku: # - Export to CVS, trunk, possibly branches. I.e. extend the system to be df91d389d5 2007-09-04 aku: # a full bridge. Either Fossil or CVS could be the master repository. df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # HACKS. I.e. I do not know if the 'fixes' I use are the correct way df91d389d5 2007-09-04 aku: # of handling the encountered situations. df91d389d5 2007-09-04 aku: # df91d389d5 2007-09-04 aku: # - File F has archives F,v and Attic/F,v. Currently I will ignore the df91d389d5 2007-09-04 aku: # file in the Attic. df91d389d5 2007-09-04 aku: # Examples: sqlite/os_unix.h df91d389d5 2007-09-04 aku: # df91d389d5 2007-09-04 aku: # - A specific revision of a file F cannot be checked out (reported df91d389d5 2007-09-04 aku: # error is 'invalid change text'). This indicates a corrupt RCS df91d389d5 2007-09-04 aku: # file, one or more delta are bad. We report but ignore the problem df91d389d5 2007-09-04 aku: # in a best-effort attempt at getting as much history as possible. df91d389d5 2007-09-04 aku: # Examples: tcllib/tklib/modules/tkpiechart/pie.tcl df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # ----------------------------------------------------------------------------- f166b0a63c 2007-08-31 aku: # Make private packages accessible. f166b0a63c 2007-08-31 aku: f166b0a63c 2007-08-31 aku: lappend auto_path [file join [file dirname [info script]] lib] df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # ----------------------------------------------------------------------------- df91d389d5 2007-09-04 aku: # Requirements df91d389d5 2007-09-04 aku: 7003caa982 2007-09-04 aku: package require Tcl 8.4 df91d389d5 2007-09-04 aku: package require cvs ; # Frontend, reading from source repository df91d389d5 2007-09-04 aku: package require fossil ; # Backend, writing to destination repository. be32ebcb41 2007-09-08 aku: package require tools::log be32ebcb41 2007-09-08 aku: be32ebcb41 2007-09-08 aku: ::tools::log::system import f166b0a63c 2007-08-31 aku: f166b0a63c 2007-08-31 aku: # ----------------------------------------------------------------------------- df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: proc main {} { be32ebcb41 2007-09-08 aku: global argv tot nto cvs fossil ntrunk stopat nmax ntfmt nmfmt be32ebcb41 2007-09-08 aku: be32ebcb41 2007-09-08 aku: commandline df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: cvs::at $cvs ; # Define location of CVS repository df91d389d5 2007-09-04 aku: cvs::scan ; # Gather revision data from the archives df91d389d5 2007-09-04 aku: cvs::csets ; # Group changes into sets df91d389d5 2007-09-04 aku: cvs::rtree ; # Build revision tree (trunk only right now). df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: set tot 0.0 df91d389d5 2007-09-04 aku: set nto 0 df91d389d5 2007-09-04 aku: be32ebcb41 2007-09-08 aku: ::tools::log::write 0 import {Begin conversion} be32ebcb41 2007-09-08 aku: ::tools::log::write 0 import {Setting up workspaces} df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: cvs::workspace ; # cd's to workspace df91d389d5 2007-09-04 aku: fossil::new ; # Uses cwd as workspace to connect to. df91d389d5 2007-09-04 aku: be32ebcb41 2007-09-08 aku: set ntrunk [cvs::ntrunk] ; set ntfmt %[string length $ntrunk]s be32ebcb41 2007-09-08 aku: set nmax [cvs::ncsets] ; set nmfmt %[string length $nmax]s be32ebcb41 2007-09-08 aku: df91d389d5 2007-09-04 aku: cvs::foreach_cset cset [cvs::root] { df91d389d5 2007-09-04 aku: import $cset 8469631cc9 2007-09-08 aku: if {$stopat == $cset} exit f166b0a63c 2007-08-31 aku: } df91d389d5 2007-09-04 aku: cvs::wsclear df91d389d5 2007-09-04 aku: be32ebcb41 2007-09-08 aku: ::tools::log::write 0 import "========= [string repeat = 61]" be32ebcb41 2007-09-08 aku: ::tools::log::write 0 import "Imported $nto [expr {($nto == 1) ? "changeset" : "changesets"}]" be32ebcb41 2007-09-08 aku: ::tools::log::write 0 import "Within [format %.2f $tot] seconds (avg [format %.2f [expr {$tot/$nto}]] seconds/changeset)" df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: fossil::destination $fossil df91d389d5 2007-09-04 aku: be32ebcb41 2007-09-08 aku: ::tools::log::write 0 import Ok. df91d389d5 2007-09-04 aku: return f166b0a63c 2007-08-31 aku: } f166b0a63c 2007-08-31 aku: df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: # ----------------------------------------------------------------------------- df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: proc commandline {} { be32ebcb41 2007-09-08 aku: global argv cvs fossil nosign debugcommit stopat df91d389d5 2007-09-04 aku: df91d389d5 2007-09-04 aku: set nosign 0 492531e3a8 2007-09-04 aku: set debugcommit 0 8469631cc9 2007-09-08 aku: set stopat {} be32ebcb41 2007-09-08 aku: set verbosity 0 492531e3a8 2007-09-04 aku: df91d389d5 2007-09-04 aku: while {[string match "-*" [set opt [lindex $argv 0]]]} { df91d389d5 2007-09-04 aku: if {$opt eq "--nosign"} { df91d389d5 2007-09-04 aku: set nosign 1 df91d389d5 2007-09-04 aku: set argv [lrange $argv 1 end] 492531e3a8 2007-09-04 aku: continue 492531e3a8 2007-09-04 aku: } 492531e3a8 2007-09-04 aku: if {$opt eq "--debugcommit"} { 492531e3a8 2007-09-04 aku: set debugcommit 1 492531e3a8 2007-09-04 aku: set argv [lrange $argv 1 end] 8469631cc9 2007-09-08 aku: continue 8469631cc9 2007-09-08 aku: } 8469631cc9 2007-09-08 aku: if {$opt eq "--stopat"} { 8469631cc9 2007-09-08 aku: set stopat [lindex $argv 1] 8469631cc9 2007-09-08 aku: set argv [lrange $argv 2 end] be32ebcb41 2007-09-08 aku: continue be32ebcb41 2007-09-08 aku: } be32ebcb41 2007-09-08 aku: if {$opt eq "-v"} { be32ebcb41 2007-09-08 aku: incr verbosity be32ebcb41 2007-09-08 aku: ::tools::log::verbosity $verbosity be32ebcb41 2007-09-08 aku: set argv [lrange $argv 1 end] df91d389d5 2007-09-04 aku: continue df91d389d5 2007-09-04 aku: } df91d389d5 2007-09-04 aku: usage f166b0a63c 2007-08-31 aku: } df91d389d5 2007-09-04 aku: if {[llength $argv] != 2} usage df91d389d5 2007-09-04 aku: foreach {cvs fossil} $argv break f166b0a63c 2007-08-31 aku: df91d389d5 2007-09-04 aku: if { df91d389d5 2007-09-04 aku: ![file exists $cvs] || df91d389d5 2007-09-04 aku: ![file readable $cvs] || df91d389d5 2007-09-04 aku: ![file isdirectory $cvs] df91d389d5 2007-09-04 aku: } { df91d389d5 2007-09-04 aku: usage "CVS directory missing, not readable, or not a directory." df91d389d5 2007-09-04 aku: } elseif {[file exists $fossil]} { df91d389d5 2007-09-04 aku: usage "Fossil destination repository exists already." f166b0a63c 2007-08-31 aku: } f166b0a63c 2007-08-31 aku: 492531e3a8 2007-09-04 aku: fossil::debugcommit $debugcommit df91d389d5 2007-09-04 aku: return f166b0a63c 2007-08-31 aku: } f166b0a63c 2007-08-31 aku: df91d389d5 2007-09-04 aku: proc usage {{text {}}} { df91d389d5 2007-09-04 aku: global argv0 df91d389d5 2007-09-04 aku: puts stderr "Usage: $argv0 ?--nosign? cvs-repository fossil-rpeository" df91d389d5 2007-09-04 aku: if {$text eq ""} return df91d389d5 2007-09-04 aku: puts stderr " $text" df91d389d5 2007-09-04 aku: exit f166b0a63c 2007-08-31 aku: } f166b0a63c 2007-08-31 aku: df91d389d5 2007-09-04 aku: proc import {cset} { be32ebcb41 2007-09-08 aku: global tot nto nosign ntrunk stopat ntfmt nmfmt be32ebcb41 2007-09-08 aku: ::tools::log::write 0 import "ChangeSet [format $nmfmt $cset] @ [format $ntfmt $nto]/$ntrunk ([format %6.2f [expr {$nto*100.0/$ntrunk}]]%)" 8469631cc9 2007-09-08 aku: 8469631cc9 2007-09-08 aku: if {$stopat == $cset} { 8469631cc9 2007-09-08 aku: fossil::commit 1 cvs2fossil $nosign \ 8469631cc9 2007-09-08 aku: [cvs::wssetup $cset] \ 8469631cc9 2007-09-08 aku: ::cvs::wsignore be32ebcb41 2007-09-08 aku: ::tools::log::write 1 import {%% STOP} 8469631cc9 2007-09-08 aku: return 8469631cc9 2007-09-08 aku: } f166b0a63c 2007-08-31 aku: df91d389d5 2007-09-04 aku: set usec [lindex [time { 8469631cc9 2007-09-08 aku: foreach {uuid ad rm ch} [fossil::commit 0 cvs2fossil $nosign \ df91d389d5 2007-09-04 aku: [cvs::wssetup $cset] \ df91d389d5 2007-09-04 aku: ::cvs::wsignore] break df91d389d5 2007-09-04 aku: } 1] 0] df91d389d5 2007-09-04 aku: cvs::uuid $cset $uuid f166b0a63c 2007-08-31 aku: df91d389d5 2007-09-04 aku: set sec [expr {$usec/1e6}] df91d389d5 2007-09-04 aku: set tot [expr {$tot + $sec}] df91d389d5 2007-09-04 aku: incr nto f166b0a63c 2007-08-31 aku: be32ebcb41 2007-09-08 aku: ::tools::log::write 2 import "== $uuid +${ad}-${rm}*${ch}" be32ebcb41 2007-09-08 aku: ::tools::log::write 2 import "st in [format %.2f $sec] sec" f166b0a63c 2007-08-31 aku: df91d389d5 2007-09-04 aku: set avg [expr {$tot/$nto}] df91d389d5 2007-09-04 aku: set max [expr {$ntrunk * $avg}] df91d389d5 2007-09-04 aku: set rem [expr {$max - $tot}] f166b0a63c 2007-08-31 aku: be32ebcb41 2007-09-08 aku: ::tools::log::write 3 import "st avg [format %.2f $avg] sec" be32ebcb41 2007-09-08 aku: ::tools::log::write 3 import "st run [format %7.2f $tot] sec [format %6.2f [expr {$tot/60}]] min [format %5.2f [expr {$tot/3600}]] hr" be32ebcb41 2007-09-08 aku: ::tools::log::write 3 import "st end [format %7.2f $max] sec [format %6.2f [expr {$max/60}]] min [format %5.2f [expr {$max/3600}]] hr" be32ebcb41 2007-09-08 aku: ::tools::log::write 3 import "st rem [format %7.2f $rem] sec [format %6.2f [expr {$rem/60}]] min [format %5.2f [expr {$rem/3600}]] hr" df91d389d5 2007-09-04 aku: return f166b0a63c 2007-08-31 aku: } f166b0a63c 2007-08-31 aku: f166b0a63c 2007-08-31 aku: # ----------------------------------------------------------------------------- f166b0a63c 2007-08-31 aku: df91d389d5 2007-09-04 aku: main df91d389d5 2007-09-04 aku: exit