| ︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
## Requirements
package require Tcl 8.4 ; # Required runtime.
package require snit ; # OO system.
package require struct::set ; # Set operations.
package require vc::fossil::import::cvs::file::rev ; # CVS per file revisions.
package require vc::fossil::import::cvs::file::sym ; # CVS per file symbols.
package require vc::tools::trouble ; # Error reporting.
package require vc::tools::log ; # User feedback
package require vc::tools::misc ; # Text formatting
# # ## ### ##### ######## ############# #####################
##
snit::type ::vc::fossil::import::cvs::file {
# # ## ### ##### ######## #############
## Public API
constructor {path usrpath executable project} {
set mypath $path
set myusrpath $usrpath
set myexecutable $executable
set myproject $project
set mytrunk [$myproject trunk]
return
}
method path {} { return $mypath }
method usrpath {} { return $myusrpath }
method project {} { return $myproject }
delegate method commitmessageof to myproject
# # ## ### ##### ######## #############
|
>
|
>
>
>
>
>
>
>
>
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
## Requirements
package require Tcl 8.4 ; # Required runtime.
package require snit ; # OO system.
package require struct::set ; # Set operations.
package require vc::fossil::import::cvs::file::rev ; # CVS per file revisions.
package require vc::fossil::import::cvs::file::sym ; # CVS per file symbols.
package require vc::fossil::import::cvs::state ; # State storage.
package require vc::tools::trouble ; # Error reporting.
package require vc::tools::log ; # User feedback
package require vc::tools::misc ; # Text formatting
# # ## ### ##### ######## ############# #####################
##
snit::type ::vc::fossil::import::cvs::file {
# # ## ### ##### ######## #############
## Public API
constructor {id path usrpath executable project} {
set myid $id
set mypath $path
set myusrpath $usrpath
set myexecutable $executable
set myproject $project
set mytrunk [$myproject trunk]
return
}
method setid {id} {
if {$myid ne ""} { trouble internal "File '$mypath' already has an id, '$myid'" }
set myid $id
return
}
method id {} { return $myid }
method path {} { return $mypath }
method usrpath {} { return $myusrpath }
method project {} { return $myproject }
delegate method commitmessageof to myproject
# # ## ### ##### ######## #############
|
| ︙ | | | ︙ | |
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
#method extend {rev commitmsg deltarange} {puts "extend $commitmsg $deltarange"}
#method done {} {puts done}
# # ## ### ##### ######## #############
## Persistence (pass II)
method persist {} {
}
method drop {} {
foreach {_ rev} [array get myrev] { $rev destroy }
foreach {_ branch} [array get mybranches] { $branch destroy }
foreach {_ taglist} [array get mytags] {
foreach tag $taglist { $tag destroy }
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#method extend {rev commitmsg deltarange} {puts "extend $commitmsg $deltarange"}
#method done {} {puts done}
# # ## ### ##### ######## #############
## Persistence (pass II)
method persist {} {
# First collect the reachable revisions and symbols, then
# assign id's to all. They are sorted so that we will have ids
# which sort in order of creation. Then we can save them. This
# is done bottom up. Revisions, then symbols. __NOTE__ This
# works only because sqlite is not checking foreign key
# references during insert. This allows to have dangling
# references which are fixed later. The longest dangling
# references are for the project level symbols, these we do
# not save here, but at the end of the pass. What we need are
# the ids, hence the two phases.
struct::list assign [$self Active] revisions symbols
foreach rev $revisions { $rev defid }
foreach sym $symbols { $sym defid }
state transaction {
foreach rev $revisions { $rev persist }
foreach sym $symbols { $sym persist }
}
return
}
method drop {} {
foreach {_ rev} [array get myrev] { $rev destroy }
foreach {_ branch} [array get mybranches] { $branch destroy }
foreach {_ taglist} [array get mytags] {
foreach tag $taglist { $tag destroy }
|
| ︙ | | | ︙ | |
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
}
return
}
# # ## ### ##### ######## #############
## State
variable mypath {} ; # Path of the file's rcs archive.
variable myusrpath {} ; # Path of the file as seen by users.
variable myexecutable 0 ; # Boolean flag 'file executable'.
variable myproject {} ; # Reference to the project object
# the file belongs to.
variable myrev -array {} ; # Maps revision number to the
# associated revision object.
|
>
|
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
}
return
}
# # ## ### ##### ######## #############
## State
variable myid {} ; # File id in the persistent state.
variable mypath {} ; # Path of the file's rcs archive.
variable myusrpath {} ; # Path of the file as seen by users.
variable myexecutable 0 ; # Boolean flag 'file executable'.
variable myproject {} ; # Reference to the project object
# the file belongs to.
variable myrev -array {} ; # Maps revision number to the
# associated revision object.
|
| ︙ | | | ︙ | |
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
|
method AddBranch {name branchnr} {
if {[info exists mybranches($branchnr)]} {
log write 1 file "In '$mypath': Branch '$branchnr' named '[$mybranches($branchnr) name]'"
log write 1 file "Cannot have second name '$name', ignoring it"
return
}
set branch [sym %AUTO% branch $branchnr [$myproject getsymbol $name]]
$branch setposition [incr mybranchcnt]
set mybranches($branchnr) $branch
return $branch
}
method AddTag {name revnr} {
set tag [sym %AUTO% tag $revnr [$myproject getsymbol $name]]
lappend mytags($revnr) $tag
return $tag
}
method RecordBasicDependencies {revnr next} {
# Handle the revision dependencies. Record them for now, do
# nothing with them yet.
|
|
|
|
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
method AddBranch {name branchnr} {
if {[info exists mybranches($branchnr)]} {
log write 1 file "In '$mypath': Branch '$branchnr' named '[$mybranches($branchnr) name]'"
log write 1 file "Cannot have second name '$name', ignoring it"
return
}
set branch [sym %AUTO% branch $branchnr [$myproject getsymbol $name] $self]
$branch setposition [incr mybranchcnt]
set mybranches($branchnr) $branch
return $branch
}
method AddTag {name revnr} {
set tag [sym %AUTO% tag $revnr [$myproject getsymbol $name] $self]
lappend mytags($revnr) $tag
return $tag
}
method RecordBasicDependencies {revnr next} {
# Handle the revision dependencies. Record them for now, do
# nothing with them yet.
|
| ︙ | | | ︙ | |
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
|
$branch setparent $rev
# If revisions were committed on the branch we store a
# reference to the branch there, and further declare
# the first child's parent to be branch's parent, and
# list this child in the parent revision.
if {[$branch haschild]} {
set childrevnr [$branch childrevnr]
set child $myrev($childrevnr)
$branch setchild $child
$child setparentbranch $branch
$child setparent $rev
$rev addchildonbranch $child
|
|
|
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
|
$branch setparent $rev
# If revisions were committed on the branch we store a
# reference to the branch there, and further declare
# the first child's parent to be branch's parent, and
# list this child in the parent revision.
if {[$branch haschildrev]} {
set childrevnr [$branch childrevnr]
set child $myrev($childrevnr)
$branch setchild $child
$child setparentbranch $branch
$child setparent $rev
$rev addchildonbranch $child
|
| ︙ | | | ︙ | |
668
669
670
671
672
673
674
675
676
677
678
679
680
681
|
# Cut out the vendor branch symbol
set vendor [$first parentbranch]
if {$vendor eq ""} { trouble internal "First NTDB revision has no branch" }
if {[$vendor parent] eq $rev11} {
$rev11 removebranch $vendor
$rev11 removechildonbranch $first
$first cutfromparentbranch
lappend myroots $first
}
# Change the type of first (typically from Change to Add):
$first retype add
|
>
|
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
|
# Cut out the vendor branch symbol
set vendor [$first parentbranch]
if {$vendor eq ""} { trouble internal "First NTDB revision has no branch" }
if {[$vendor parent] eq $rev11} {
$rev11 removebranch $vendor
$rev11 removechildonbranch $first
$vendor cutchild
$first cutfromparentbranch
lappend myroots $first
}
# Change the type of first (typically from Change to Add):
$first retype add
|
| ︙ | | | ︙ | |
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
|
ldelete myroots $root
if {[$root haschild]} {
set child [$root child]
$child cutfromparent
lappend myroots $child
}
# Remove the branches spawned by the revision to be
# deleted. If the branch has revisions they should already
# use operation 'add', no need to change that. The first
# revision on each branch becomes a new and disconnected
# root.
foreach branch [$root branches] {
if {![$branch haschild]} continue
set first [$branch child]
$first cutfromparentbranch
$first cutfromparent
lappend myroots $first
}
$root removeallbranches
# Tagging a dead revision doesn't do anything, so remove
# any tags that were set on it.
|
|
>
|
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
|
ldelete myroots $root
if {[$root haschild]} {
set child [$root child]
$child cutfromparent
lappend myroots $child
}
# Cut out the branches spawned by the revision to be
# deleted. If the branch has revisions they should already
# use operation 'add', no need to change that. The first
# revision on each branch becomes a new and disconnected
# root.
foreach branch [$root branches] {
if {![$branch haschild]} continue
set first [$branch child]
$first cutfromparentbranch
$first cutfromparent
$branch cutchild
lappend myroots $first
}
$root removeallbranches
# Tagging a dead revision doesn't do anything, so remove
# any tags that were set on it.
|
| ︙ | | | ︙ | |
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
|
set branch [$root parentbranch]
set parent [$root parent]
set child [$root child]
ldelete myroots $root
lappend myroots $child
$child cutfromparent
$parent removebranch $branch
$parent removechildonbranch $root
}
return
}
method LinesOfDevelopment {} {
|
>
>
|
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
|
set branch [$root parentbranch]
set parent [$root parent]
set child [$root child]
ldelete myroots $root
lappend myroots $child
$branch cutchild
$child cutfromparent
$parent removebranch $branch
$parent removechildonbranch $root
}
return
}
method LinesOfDevelopment {} {
|
| ︙ | | | ︙ | |
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
|
$tag setlod $mytrunk
}
set root [$root child]
}
return
}
# # ## ### ##### ######## #############
## Configuration
pragma -hastypeinfo no ; # no type introspection
pragma -hasinfo no ; # no object introspection
pragma -hastypemethods no ; # type is not relevant.
# # ## ### ##### ######## #############
}
namespace eval ::vc::fossil::import::cvs {
namespace export file
namespace eval file {
# Import not required, already a child namespace.
# namespace import ::vc::fossil::import::cvs::file::rev
# namespace import ::vc::fossil::import::cvs::file::sym
namespace import ::vc::tools::misc::*
namespace import ::vc::tools::trouble
namespace import ::vc::tools::log
}
}
# # ## ### ##### ######## ############# #####################
## Ready
package provide vc::fossil::import::cvs::file 1.0
return
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
|
$tag setlod $mytrunk
}
set root [$root child]
}
return
}
method Active {} {
set revisions {}
set symbols {}
foreach root [$self LinesOfDevelopment] {
if {[$root hasparentbranch]} { lappend symbols [$root parentbranch] }
while {$root ne ""} {
lappend revisions $root
foreach tag [$root tags] { lappend symbols $tag }
foreach branch [$root branches] { lappend symbols $branch }
set lod [$root lod]
if {![$lod istrunk]} { lappend symbols $lod }
set root [$root child]
}
}
return [list [lsort -unique -dict $revisions] [lsort -unique -dict $symbols]]
}
# # ## ### ##### ######## #############
## Configuration
pragma -hastypeinfo no ; # no type introspection
pragma -hasinfo no ; # no object introspection
pragma -hastypemethods no ; # type is not relevant.
# # ## ### ##### ######## #############
}
namespace eval ::vc::fossil::import::cvs {
namespace export file
namespace eval file {
# Import not required, already a child namespace.
# namespace import ::vc::fossil::import::cvs::file::rev
# namespace import ::vc::fossil::import::cvs::file::sym
namespace import ::vc::tools::misc::*
namespace import ::vc::tools::trouble
namespace import ::vc::tools::log
namespace import ::vc::fossil::import::cvs::state
}
}
# # ## ### ##### ######## ############# #####################
## Ready
package provide vc::fossil::import::cvs::file 1.0
return
|