Check-in [7b2619b7ef]
Not logged in
Overview

SHA1 Hash:7b2619b7ef45faa0c4b3b56858db692691a9e688
Date: 2007-09-13 08:02:26
User: aku
Comment:Unhacked the fossil backend. IOW reworked the API and made it nicer, more structured, better command and option names. Gave the internals more structure, and simplified the handling of -breakat (old -stopat breakpoint). Updated users, and updated the user visible switches as well. Added a -h switch for help.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified tools/import-cvs.tcl from [5138f35894] to [c75797ae19].

@@ -66,15 +66,16 @@
     set verbosity 0
 
     clinit
     while {[string match "-*" [set opt [this]]]} {
 	switch -exact -- $opt {
-	    --nosign      {        import::configure -nosign      1 }
-	    --debugcommit {        import::configure -debugcommit 1 }
-	    --stopat      { next ; import::configure -stopat [this] }
+	    --breakat     { next ; import::configure -breakat [this] }
+	    --nosign      {        import::configure -nosign       1 }
+	    --saveto      { next ; import::configure -saveto  [file normalize [this]] }
 	    -v            { incr verbosity ; ::vc::tools::log::verbosity $verbosity }
-	    default usage
+	    -h            -
+	    default       usage
 	}
 	next
     }
 
     remainder
@@ -119,15 +120,21 @@
     return
 }
 
 proc usage {{text {}}} {
     global argv0
-    puts stderr "Usage: $argv0 ?--nosign? ?-v? ?--stopat id? ?--debugcommit? cvs-repository fossil-repository"
-    if {$text eq ""} return
-    puts stderr "       $text"
+    puts stderr "Usage: $argv0 ?-v? ?--nosign? ?--breakat id? ?--saveto path? cvs-repository fossil-repository"
+    if {$text eq ""} {
+	puts stderr "       --nosign:  Do not sign the imported changesets."
+	puts stderr "       --breakat: Stop just before committing the identified changeset."
+	puts stderr "       --saveto:  Save commit command to the specified file."
+	puts stderr "       -v:        Increase log verbosity. Can be used multiple times."
+    } else {
+	puts stderr "       $text"
+    }
     exit
 }
 
 # -----------------------------------------------------------------------------
 
 main
 exit

Modified tools/lib/fossil.tcl from [d2dc326337] to [a0b0c0df17].

@@ -16,109 +16,86 @@
 }
 
 # -----------------------------------------------------------------------------
 # API
 
-# Define repository file, and connect to workspace in CWD.
-
-proc ::vc::fossil::ws::new {} {
-    variable fr     [file normalize [fileutil::tempfile import2_fsl_rp_]]
-
-    # pwd = workspace
-    dova new  $fr ; # create and
-    dova open $fr ; # connect
-
-    write 0 fossil "Repository: $fr"
-
-    return $fr
-}
-
-# Move generated fossil repository to final destination
-
-proc ::vc::fossil::ws::destination {path} {
-    variable fr
-    file rename $fr $path
-    return
-}
-
-namespace eval ::vc::fossil::ws {
-    # Repository file
-    variable fr {}
-
-    # Debug the commit command (write a Tcl script containing the
-    # exact command used). And the file the data goes to.
-    variable debugcommit 0
-    variable dcfile      {}
-}
-
-proc ::vc::fossil::ws::debugcommit {flag} {
-    variable debugcommit $flag
-    if {$debugcommit} {
-	variable dcfile [file normalize cvs2fossil_commit.tcl]
+# vc::fossil::ws::configure key value         - Configure the subsystem.
+# vc::fossil::ws::begin     src               - Start new workspace for directory
+# vc::fossil::ws::done      dst               - Close workspace and copy to destination.
+# vc::fossil::ws::commit    cset usr time msg - Look for changes and commit as new revision.
+
+# Configuration keys:
+#
+# -nosign  bool		default 0 (= sign imported changesets)
+# -breakat num		default empty, no breakpoint.
+#			Otherwise stop before committing the identified changeset.
+# -saveto  path		default empty, no saving.
+#			Otherwise save the commit command to a file.
+# -appname string	Default empty. Text to add to all commit messages.
+# -ignore  cmdprefix	Command to check if a file is relevant to the commit or not.
+#			Signature: cmdprefix path -> bool; true => ignore.
+
+# -----------------------------------------------------------------------------
+# API Implementation
+
+proc ::vc::fossil::ws::configure {key value} {
+    variable nosign
+    variable breakat
+    variable saveto
+    variable appname
+    variable ignore
+
+    switch -exact -- $key {
+	-appname { set appname $value }
+	-breakat { set breakat $value }
+	-ignore  { set ignore  $value }
+	-nosign {
+	    if {![string is boolean -strict $value]} {
+		return -code error "Expected boolean, got \"$value\""
+	    }
+	    set nosign $value
+	}
+	-saveto  { set saveto $value }
+	default {
+	    return -code error "Unknown switch $key, expected one of \
+                                   -appname, -breakat, -ignore, -nosign, or -saveto"
+	}
     }
     return
 }
 
-proc ::vc::fossil::ws::commit {break appname nosign meta ignore} {
-    variable lastuuid
-    variable debugcommit
-    variable dcfile
+proc ::vc::fossil::ws::begin {origin} {
+    variable rp [file normalize [fileutil::tempfile import2_fsl_rp_]]
+
+    cd $origin
+    dova new  $rp ; # create and ...
+    dova open $rp ; # ... connect
+
+    write 0 fossil "Repository: $rp"
+    return
+}
+
+proc ::vc::fossil::ws::done {destination} {
+    variable rp
+    file rename -force $rp $destination
+    set rp {}
+    return
+}
+
+proc ::vc::fossil::ws::commit {cset user timestamp message} {
+    variable lastuuid
 
     # Commit the current state of the workspace. Scan for new and
     # removed files and issue the appropriate fossil add/rm commands
     # before actually comitting.
 
-    # Modified/Removed files first, that way there won't be any ADDED
-    # indicators. Nor REMOVED, only EDITED. Removed files show up as
-    # EDITED while they are not registered as removed.
-
-    set added   0
-    set removed 0
-    set changed 0
-
-    foreach line [split [dova changes] \n] {
-	regsub {^\s*EDITED\s*} $line {} path
-	if {[IGNORE $ignore $path]} continue
-
-	if {![file exists $path]} {
-	    dova rm $path
-	    incr removed
-	    write 2 fossil "-  $path"
-	} else {
-	    incr changed
-	    write 2 fossil "*  $path"
-	}
-    }
-
-    # Now look for unregistered added files.
-
-    foreach path [split [dova extra] \n] {
-	if {[IGNORE $ignore $path]} continue
-	dova add $path
-	incr added
-	write 2 fossil "+  $path"
-    }
+    HandleChanges added removed changed
 
     # Now commit, using the provided meta data, and capture the uuid
     # of the new baseline.
 
-    foreach {user message tstamp} $meta break
-
-    set message [join [list \
-			   "-- Originally by $user @ $tstamp" \
-			   "-- Imported by $appname" \
-			   $message] \n]
-
-    set cmd [list commit -m $message]
-    if {$nosign} { lappend cmd --nosign }
-
-    if {$debugcommit} {
-	fileutil::writeFile $dcfile "$cmd\n"
-    }
-
-    # Stop, do not actually commit.
-    if {$break} return
+    set cmd [Command $cset [Message $user $timestamp $message]]
 
     if {[catch {
 	do $cmd
     } line]} {
 	if {![string match "*nothing has changed*" $line]} {
@@ -133,28 +110,106 @@
 	write 1 fossil "UNCHANGED, keeping last"
 
 	return [list $lastuuid 0 0 0]
     }
 
-    set line [string trim $line]
-    regsub -nocase -- {^\s*New_Version:\s*} $line {} uuid
+    # Extract the uuid of the new revision.
+    regsub -nocase -- {^\s*New_Version:\s*} [string trim $line] {} uuid
 
     set lastuuid $uuid
     return [list $uuid $added $removed $changed]
 }
 
 # -----------------------------------------------------------------------------
-# Internal helper commands
+# Internal helper commands, and data structures.
+
+proc ::vc::fossil::ws::HandleChanges {av rv cv} {
+    upvar 1 $av added $rv removed $cv changed
+
+    set added   0
+    set removed 0
+    set changed 0
+
+    # Look for modified/removed files first, that way there won't be
+    # any ADDED indicators. Nor REMOVED, only EDITED. Removed files
+    # show up as EDITED while they are not registered as removed.
+
+    foreach line [split [do changes] \n] {
+        regsub {^\s*EDITED\s*} $line {} path
+        if {[Ignore $path]} continue
+
+        if {![file exists $path]} {
+	    dova rm $path
+            incr removed
+            write 2 fossil "-  $path"
+        } else {
+            incr changed
+            write 2 fossil "*  $path"
+        }
+    }
+
+    # Now look for unregistered added files.
+
+    foreach path [split [do extra] \n] {
+        if {[Ignore $path]} continue
+        dova add $path
+        incr added
+        write 2 fossil "+  $path"
+    }
+
+    return
+}
+
+proc ::vc::fossil::ws::Message {user timestamp message} {
+    variable appname
+    set lines {}
+    lappend lines "-- Originally by $user @ $timestamp"
+    if {$appname ne ""} {
+	lappend lines "-- Imported by $appname"
+    }
+    lappend lines [string trim $message]
+    return [join $lines \n]
+}
+
+proc ::vc::fossil::ws::Command {cset message} {
+    variable nosign
+    variable saveto
+    variable breakat
+
+    set cmd [list commit -m $message]
+
+    if {$nosign}           { lappend cmd --nosign }
+    if {$saveto ne ""}     { fileutil::writeFile $saveto "$cmd\n" }
+
+    if {$breakat eq $cset} {
+	write 0 fossil Stopped.
+	exit 0
+    }
+
+    return $cmd
+}
 
-proc ::vc::fossil::ws::IGNORE {ignore path} {
+proc ::vc::fossil::ws::Ignore {path} {
+    variable ignore
+    if {![llength $ignore]} {return 0}
     return [uplevel #0 [linsert $ignore end $path]]
 }
 
 namespace eval ::vc::fossil::ws {
-    namespace export new destination debugcommit commit
+    # Configuration settings.
+    variable nosign 0   ; # Sign imported changesets
+    variable breakat {} ; # Do not stop
+    variable saveto  {} ; # Do not save commit message
+    variable appname {} ; # Name of importer application using the package.
+    variable ignore  {} ; # No files to ignore.
+
+    variable rp       {} ; # Repository the package works on.
+    variable lastuuid {} ; # Uuid of last imported changeset.
+
+    namespace export configure begin done commit
 }
 
 # -----------------------------------------------------------------------------
 # Ready
 
 package provide vc::fossil::ws 1.0
 return

Modified tools/lib/importcvs.tcl from [ab3e3cfde7] to [0d2f09ecb4].

@@ -12,10 +12,13 @@
 namespace eval ::vc::fossil::import::cvs {
     vc::tools::log::system import
     namespace import ::vc::tools::log::write
     namespace eval cvs    { namespace import ::vc::cvs::ws::* }
     namespace eval fossil { namespace import ::vc::fossil::ws::* }
+
+    fossil::configure -appname cvs2fossil
+    fossil::configure -ignore  ::vc::cvs::ws::wsignore
 }
 
 # -----------------------------------------------------------------------------
 # API
 
@@ -22,54 +25,39 @@
 # Configuration
 #
 #	vc::fossil::import::cvs::configure key value - Set configuration
 #
 #	Legal keys:	-nosign		<bool>, default false
-#			-debugcommit	<bool>, default false
-#			-stopat		<int>,  default :none:
+#			-breakat	<int>,  default :none:
+#			-saveto		<path>, default :none:
 #
 # Functionality
 #
 #	vc::fossil::import::cvs::run src dst         - Perform an import.
 
 # -----------------------------------------------------------------------------
 # API Implementation - Functionality
 
 proc ::vc::fossil::import::cvs::configure {key value} {
-    variable nosign
-    variable stopat
-
+    # The options are simply passed through to the fossil importer
+    # backend.
     switch -exact -- $key {
-	-debugcommit {
-	    if {![string is boolean -strict $value]} {
-		return -code error "Expected boolean, got \"$value\""
-	    }
-	    fossil::debugcommit $value
-	}
-	-nosign {
-	    if {![string is boolean -strict $value]} {
-		return -code error "Expected boolean, got \"$value\""
-	    }
-	    set nosign $value
-	}
-	-stopat {
-	    set stopat $value
-	}
+	-breakat { fossil::configure -breakat $value }
+	-nosign  { fossil::configure -nosign  $value }
+	-saveto  { fossil::configure -saveto  $value }
 	default {
 	    return -code error "Unknown switch $key, expected one of \
-                                   -debugcommit, -nosign, or -stopat"
+                                   -breakat, -nosign, or -saveto"
 	}
     }
     return
 }
 
 # Import the CVS repository found at directory 'src' into the new
 # fossil repository at 'dst'.
 
 proc ::vc::fossil::import::cvs::run {src dst} {
-    variable stopat
-
     cvs::at $src  ; # Define location of CVS repository
     cvs::scan     ; # Gather revision data from the archives
     cvs::csets    ; # Group changes into sets
     cvs::rtree    ; # Build revision tree (trunk only right now).
 
@@ -77,12 +65,12 @@
     set nto 0
 
     write 0 import {Begin conversion}
     write 0 import {Setting up workspaces}
 
-    cvs::workspace ; # cd's to workspace
-    fossil::new    ; # Uses cwd as workspace to connect to.
+    cvs::workspace      ; # cd's to workspace
+    fossil::begin [pwd] ; # Uses cwd as workspace to connect to.
 
     set ntrunk [cvs::ntrunk] ; set ntfmt %[string length $ntrunk]s
     set nmax   [cvs::ncsets] ; set nmfmt %[string length $nmax]s
 
     cvs::foreach_cset cset [cvs::root] {
@@ -92,14 +80,12 @@
 
     write 0 import "========= [string repeat = 61]"
     write 0 import "Imported $nto [expr {($nto == 1) ? "changeset" : "changesets"}]"
     write 0 import "Within [format %.2f $tot] seconds (avg [format %.2f [expr {$tot/$nto}]] seconds/changeset)"
 
-    if {$stopat == $cset} return
-
     cvs::wsclear
-    fossil::destination $dst
+    fossil::close $dst
     write 0 import Ok.
     return
 }
 
 # -----------------------------------------------------------------------------
@@ -124,25 +110,13 @@
     write 3 import "st rem [format %7.2f $rem] sec [format %6.2f [expr {$rem/60}]] min [format %5.2f [expr {$rem/3600}]] hr"
     return
 }
 
 proc ::vc::fossil::import::cvs::OneChangeSet {cset} {
-    variable nosign
-    variable stopat
-
-    if {$stopat == $cset} {
-	fossil::commit 1 cvs2fossil $nosign \
-	    [cvs::wssetup $cset] ::vc::cvs::ws::wsignore
-	write 0 import Stopped.
-	return -code break
-    }
-
     set usec [lindex [time {
-	foreach {uuid ad rm ch} \
-	    [fossil::commit 0 cvs2fossil $nosign \
-		 [cvs::wssetup $cset] ::vc::cvs::ws::wsignore] \
-	    break
+	foreach {user message timestamp} [cvs::wssetup $cset] break
+	foreach {uuid ad rm ch} [fossil::commit $cset $user $timestamp $message] break
     } 1] 0]
     cvs::uuid $cset $uuid
 
     set sec [expr {$usec/1e6}]
 
@@ -153,17 +127,13 @@
 }
 
 # -----------------------------------------------------------------------------
 
 namespace eval ::vc::fossil::import::cvs {
-    variable debugcommit 0  ; # Debug the commit operation.
-    variable nosign      0  ; # Require signing
-    variable stopat      {} ; # Stop nowhere
-
     namespace export run configure
 }
 
 # -----------------------------------------------------------------------------
 # Ready
 
 package provide vc::fossil::import::cvs 1.0
 return