Check-in [7eaa420a23]
Not logged in
Overview

SHA1 Hash:7eaa420a232a7aac94bb11455a40ef6cec0321c0
Date: 2007-11-05 09:04:25
User: aku
Comment:Extended options processing to handle --exclude, --force-tag, and --force-branch options. Extended project::sym class with in-memkory databases to hold the option information and replaced the 'UserConfig' placeholder with the actual code using the new databases to determine symbol types based on user-requests. Extended the pass itself with code performing various checks on the results of type determination, partially paranoia, partially to find genuine bad requests (excluding symbols with unexcluded blockers, making a symbol with commits on it a tag, ...). NYI: Computation of the prefered parent for all symbols.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified tools/cvs2fossil/lib/c2f_option.tcl from [ebc8b51de9] to [d7008b5e1a].

@@ -25,10 +25,11 @@
 package require vc::tools::misc                       ; # Misc. path reformatting.
 package require vc::fossil::import::cvs::pass         ; # Pass management
 package require vc::fossil::import::cvs::pass::collar ; # Pass I.
 package require vc::fossil::import::cvs::repository   ; # Repository management
 package require vc::fossil::import::cvs::state        ; # State storage
+package require vc::fossil::import::cvs::project::sym ; # Project level symbols
 
 # # ## ### ##### ######## ############# #####################
 ##
 
 snit::type ::vc::fossil::import::cvs::option {
@@ -42,17 +43,17 @@
     # --project
     # -v, --verbose
     # -q, --quiet
     # --state (conversion status, ala config.cache)
     # --trunk-only
+    # --exclude, --force-tag, --force-branch
 
     # -o, --output
     # --dry-run
     # --force-branch RE
     # --force-tag RE
     # --symbol-transform RE:XX
-    # --exclude
 
     # # ## ### ##### ######## #############
     ## Public API, Methods
 
     typemethod process {arguments} {
@@ -73,10 +74,13 @@
 		--verbose                   { log verbose }
 		-q                          -
 		--quiet                     { log quiet }
 		--state                     { state use [Value arguments] }
 		--trunk-only                { repository trunkonly! }
+		--exclude                   { project::sym exclude     [Value arguments] }
+		--force-tag                 { project::sym forcetag    [Value arguments] }
+		--force-branch              { project::sym forcebranch [Value arguments] }
 		default {
 		    Usage $badoption$option\n$gethelp
 		}
 	    }
 	}
@@ -116,10 +120,26 @@
 	trouble info "                               Prevent abort when conflicting archives"
 	trouble info "                               were found in both regular and Attic."
 	trouble info ""
 	trouble info "    --state PATH               Save state to the specified file, and"
 	trouble info "                               load state of previous runs from it too."
+	trouble info ""
+	trouble info "    --exclude ?PROJECT:?SYMBOL Exclude the named symbol from all or"
+	trouble info "                               just the specified project. Both project"
+	trouble info "                               and symbol names are glob patterns."
+	trouble info ""
+	trouble info "    --force-tag ?PROJECT:?SYMBOL"
+	trouble info "                               Force the named symbol from all or just"
+	trouble info "                               the specified project to be converted as"
+	trouble info "                               tag. Both project and symbol names are"
+	trouble info "                               glob patterns."
+	trouble info ""
+	trouble info "    --force-branch ?PROJECT:?SYMBOL"
+	trouble info "                               Force the named symbol from all or just"
+	trouble info "                               the specified project to be converted as"
+	trouble info "                               branch. Both project and symbol names"
+	trouble info "                               are glob patterns."
 	trouble info ""
 
 	# --project, --cache
 	# ...
 	return
@@ -188,20 +208,23 @@
 }
 
 namespace eval ::vc::fossil::import::cvs {
     namespace export option
     namespace eval option {
-	namespace import ::vc::tools::trouble
-	namespace import ::vc::tools::log
 	namespace import ::vc::tools::misc::striptrailingslash
 	namespace import ::vc::fossil::import::cvs::pass
 	namespace import ::vc::fossil::import::cvs::pass::collar
 	namespace import ::vc::fossil::import::cvs::repository
 	namespace import ::vc::fossil::import::cvs::state
+	namespace eval project {
+	    namespace import ::vc::fossil::import::cvs::project::sym
+	}
+	namespace import ::vc::tools::trouble
+	namespace import ::vc::tools::log
     }
 }
 
 # # ## ### ##### ######## ############# #####################
 ## Ready
 
 package provide vc::fossil::import::cvs::option 1.0
 return

Modified tools/cvs2fossil/lib/c2f_pcollrev.tcl from [98fd60f570] to [903f027831].

@@ -315,12 +315,12 @@
 	}
 
 	repository printrevstatistics
 	repository persistrev
 
-	log write 1 collrev "Scan completed"
 	Paranoia
+	log write 1 collrev "Scan completed"
 	return
     }
 
     typemethod discard {} {
 	# Pass manager interface. Executed for all passes after the

Modified tools/cvs2fossil/lib/c2f_pcollsym.tcl from [77182f7016] to [c53c706e1d].

@@ -9,24 +9,21 @@
 # individuals.  For exact contribution history, see the revision
 # history and logs, available at http://fossil-scm.hwaci.com/fossil
 # # ## ### ##### ######## ############# #####################
 
 ## Pass III. This pass divides the symbols collected by the previous
-## pass into branches, tags, and excludes. The latter are __not__
-## deleted by this pass, only marked. It is the next pass,
-## 'FilterSym', which performs the actual deletion.
+## pass into branches, tags, and excludes. The latter are also
+## partially deleted by this pass, not only marked. It is the next
+## pass however, 'FilterSym', which performs the full deletion.
 
 # # ## ### ##### ######## ############# #####################
 ## Requirements
 
 package require Tcl 8.4                               ; # Required runtime.
 package require snit                                  ; # OO system.
-#package require fileutil::traverse                    ; # Directory traversal.
-#package require fileutil                              ; # File & path utilities.
-#package require vc::tools::trouble                    ; # Error reporting.
-package require vc::tools::log                        ; # User feedback.
-#package require vc::fossil::import::cvs::pass         ; # Pass management.
+package require vc::tools::trouble                    ; # Error reporting.
+package require vc::tools::log                        ; # User feedback.
 package require vc::fossil::import::cvs::repository   ; # Repository management.
 package require vc::fossil::import::cvs::state        ; # State storage.
 package require vc::fossil::import::cvs::project::sym ; # Project level symbols
 
 # # ## ### ##### ######## ############# #####################
@@ -49,11 +46,10 @@
 	# pass.
 
 	state reading symbol
 	state reading blocker
 	state reading parent
-
 	return
     }
 
     typemethod load {} {
 	# TODO
@@ -69,24 +65,131 @@
 
 	    project::sym printrulestatistics
 	    project::sym printtypestatistics
 	}
 
+	if {![trouble ?]} {
+	    UnconvertedSymbols
+	    BadSymbolTypes
+	    BlockedExcludes
+	    InvalidTags
+	}
+
+	if {![trouble ?]} {
+	    DropExcludedSymbolsFromReferences
+	}
+
 	log write 1 collsym "Collation completed"
 	return
     }
 
     typemethod discard {} {
 	# Pass manager interface. Executed for all passes after the
 	# run passes, to remove all data of this pass from the state,
 	# as being out of date.
-
 	return
     }
 
     # # ## ### ##### ######## #############
     ## Internal methods
+
+    proc UnconvertedSymbols {} {
+	# Paranoia - Have we left symbols without conversion
+	# information (i.e. with type 'undefined') ?
+
+	set undef [project::sym undef]
+
+	foreach {pname sname} [state run {
+	    SELECT P.name, S.name
+	    FROM   project P, symbol S
+	    WHERE  P.pid = S.pid
+	    AND    S.type = $undef
+	}] {
+	    trouble fatal "$pname : The symbol '$sname' was left undefined"
+	}
+	return
+    }
+
+    proc BadSymbolTypes {} {
+	# Paranoia - Have we left symbols with bogus conversion
+	# information (type out of the valid range (excluded, branch,
+	# tag)) ?
+
+	foreach {pname sname} [state run {
+	    SELECT P.name, S.name
+	    FROM   project P, symbol S
+	    WHERE  P.pid = S.pid
+	    AND    S.type NOT IN (0,1,2)
+	}] {
+	    trouble fatal "$pname : The symbol '$sname' has no proper conversion type"
+	}
+	return
+    }
+
+    proc BlockedExcludes {} {
+	# Paranoia - Have we scheduled symbols for exclusion without
+	# also excluding their dependent symbols ?
+
+	set excl [project::sym excluded]
+
+	foreach {pname sname bname} [state run {
+	    SELECT P.name, S.name, SB.name
+	    FROM   project P, symbol S, blocker B, symbol SB
+	    WHERE  P.pid = S.pid
+	    AND    S.type = $excl
+	    AND    S.sid = B.sid
+	    AND    B.bid = SB.sid
+	    AND    SB.type != $excl
+	}] {
+	    trouble fatal "$pname : The symbol '$sname' cannot be excluded as the unexcluded symbol '$bname' depends on it."
+	}
+	return
+    }
+
+    proc InvalidTags {} {
+	# Paranoia - Have we scheduled symbols for conversion as tags
+	# which absolutely cannot be converted as tags due to commits
+	# made on them ?
+
+	# In other words, this checks finds out if the user has asked
+	# nonsensical conversions of symbols, which should have been
+	# left to the heuristics, most specifically
+	# 'project::sym.HasCommits()'.
+
+	set tag [project::sym tag]
+
+	foreach {pname sname} [state run {
+	    SELECT P.name, S.name
+	    FROM   project P, symbol S
+	    WHERE  P.pid = S.pid
+	    AND    S.type = $tag
+	    AND    S.commit_count > 0
+	}] {
+	    trouble fatal "$pname : The symbol '$sname' cannot be forced to be converted as tag because it has commits."
+	}
+	return
+    }
+
+    proc DropExcludedSymbolsFromReferences {} {
+	# The excluded symbols cann be used as blockers nor as
+	# possible parent for other symbols. We now drop the relevant
+	# entries to prevent them from causing confusion later on.
+
+	set excl [project::sym excluded]
+
+	state run {
+	    DELETE FROM blocker
+	    WHERE bid IN (SELECT sid
+			  FROM   symbol
+			  WhERE  type = $excl);
+	    DELETE FROM parent
+	    WHERE pid IN (SELECT sid
+			  FROM   symbol
+			  WhERE  type = $excl);
+	}
+	return
+    }
 
     # # ## ### ##### ######## #############
     ## Configuration
 
     pragma -hasinstances   no ; # singleton
@@ -102,11 +205,11 @@
 	namespace import ::vc::fossil::import::cvs::repository
 	namespace import ::vc::fossil::import::cvs::state
 	namespace eval project {
 	    namespace import ::vc::fossil::import::cvs::project::sym
 	}
-	#namespace import ::vc::tools::trouble
+	namespace import ::vc::tools::trouble
 	namespace import ::vc::tools::log
 	log register collsym
     }
 }
 

Modified tools/cvs2fossil/lib/c2f_psym.tcl from [9138dfe62a] to [69d3d4a188].

@@ -178,10 +178,61 @@
     variable mytype {} ; # The type chosen for the symbol to use in
 			 # the conversion.
 
     # # ## ### ##### ######## #############
 
+    typemethod exclude {pattern} {
+	# Store the pattern in memory for use by the code doing type
+	# determination.
+
+	lappend myexcludepattern [ProcessPattern $pattern exclusion]
+	return
+    }
+
+    typemethod forcetag {pattern} {
+	# Store the pattern in memory for use by the code doing type
+	# determination.
+
+	lappend myforcepattern [ProcessPattern $pattern force-tag] $mytag
+	return
+    }
+
+    typemethod forcebranch {pattern} {
+	# Store the pattern in memory for use by the code doing type
+	# determination.
+
+	lappend myforcepattern [ProcessPattern $pattern force-branch] $mybranch
+	return
+    }
+
+    proc ProcessPattern {pattern label} {
+	if {[string match *:*:* $pattern]} {
+	    # Bad syntax for the pattern, using multiple colons.
+
+	    trouble fatal "Bad $label pattern '$pattern'"
+	} elseif {![string match *:* $pattern]} {
+	    # When only a symbol pattern is specified it applies to
+	    # all projects.
+
+	    return [list * $pattern]
+	} else {
+	    # Both project and symbol patterns are present, we split
+	    # them apart now for storage and easier extraction later.
+
+	    return [split $pattern :]
+	}
+    }
+
+    typevariable myexcludepattern {} ; # List of patterns specifying
+				       # the symbols to exclude from
+				       # conversion. Tags and/or
+				       # branches.
+
+    typevariable myforcepattern {} ; # List of patterns and types
+				     # specifying which symbols to
+				     # force to specific types.
+
     typemethod getsymtypes {} {
 	foreach {tid name} [state run {
 	    SELECT tid, name FROM symtype;
 	}] { set mysymtype($tid) $name }
 	return
@@ -191,10 +242,14 @@
     typevariable myexcluded        0 ; # Code for symbols which are excluded.
     typevariable mytag             1 ; # Code for symbols which are tags.
     typevariable mybranch          2 ; # Code for symbols which are branches.
     typevariable myundef           3 ; # Code for symbols of unknown type.
     typevariable mysymtype -array {} ; # Map from type code to label for the log.
+
+    typemethod undef    {} { return $myundef    }
+    typemethod excluded {} { return $myexcluded }
+    typemethod tag      {} { return $mytag      }
 
     typemethod printrulestatistics {} {
 	log write 2 symbol "Rule usage statistics:"
 
 	set fmt %[string length $mynum]s
@@ -246,11 +301,35 @@
 
     # # ## ### ##### ######## #############
     ## Internal methods
 
     method UserConfig {} {
-	# No user based guidance yet.
+	set project [$myproject base]
+
+	# First check if the user requested the exclusion of the
+	# symbol from conversion.
+
+	foreach ex $myexcludepattern {
+	    struct::list assign $ex pp sp
+	    if {![string match $pp $project]} continue
+	    if {![string match $sp $myname]}  continue
+	    return $myexcluded
+	}
+
+	# If the symbol is not excluded further check if the user
+	# forces its conversion as a specific type.
+
+	foreach {ex stype} $myforcepattern {
+	    struct::list assign $ex pp sp
+	    if {![string match $pp $project]} continue
+	    if {![string match $sp $myname]}  continue
+	    return $stype
+	}
+
+	# Nothing is forced, have the main system hand the symbol over
+	# to the regular heuristics.
+
 	return $myundef
     }
 
     method Unambigous {} {
 	# If a symbol is used unambiguously as a tag/branch, convert

Modified tools/cvs2fossil/lib/trouble.tcl from [2697d806a7] to [f653273970].

@@ -50,10 +50,18 @@
     typemethod show {} {
 	foreach m $myinfo  { log write 0 ""      $m }
 	foreach m $mywarn  { log write 0 warning $m }
 	foreach m $myfatal { log write 0 fatal   $m }
 	return
+    }
+
+    typemethod ? {} {
+	return [expr {
+	    [llength $myinfo] ||
+	    [llength $mywarn] ||
+	    [llength $myfatal]
+	}]
     }
 
     typemethod abort? {} {
 	if {
 	    ![llength $myinfo] &&