Fossil SCM

fossil-scm / tools / cvs2fossil / lib / c2f_pcollsym.tcl
Blame History Raw 319 lines
1
## -*- tcl -*-
2
# # ## ### ##### ######## ############# #####################
3
## Copyright (c) 2007 Andreas Kupries.
4
#
5
# This software is licensed as described in the file LICENSE, which
6
# you should have received as part of this distribution.
7
#
8
# This software consists of voluntary contributions made by many
9
# individuals. For exact contribution history, see the revision
10
# history and logs, available at http://fossil-scm.hwaci.com/fossil
11
# # ## ### ##### ######## ############# #####################
12
13
## Pass III. This pass divides the symbols collected by the previous
14
## pass into branches, tags, and excludes. The latter are also
15
## partially deleted by this pass, not only marked. It is the next
16
## pass however, 'FilterSym', which performs the full deletion.
17
18
# # ## ### ##### ######## ############# #####################
19
## Requirements
20
21
package require Tcl 8.4 ; # Required runtime.
22
package require snit ; # OO system.
23
package require vc::tools::trouble ; # Error reporting.
24
package require vc::tools::log ; # User feedback.
25
package require vc::fossil::import::cvs::repository ; # Repository management.
26
package require vc::fossil::import::cvs::state ; # State storage.
27
package require vc::fossil::import::cvs::project::sym ; # Project level symbols
28
29
# # ## ### ##### ######## ############# #####################
30
## Register the pass with the management
31
32
vc::fossil::import::cvs::pass define \
33
CollateSymbols \
34
{Collate symbols} \
35
::vc::fossil::import::cvs::pass::collsym
36
37
# # ## ### ##### ######## ############# #####################
38
##
39
40
snit::type ::vc::fossil::import::cvs::pass::collsym {
41
# # ## ### ##### ######## #############
42
## Public API
43
44
typemethod setup {} {
45
# Define names and structure of the persistent state of this
46
# pass.
47
48
state use project
49
state use symbol
50
state use symtype
51
state use blocker
52
state use parent
53
54
state extend preferedparent {
55
-- For each symbol the prefered parent. This describes the
56
-- tree of the found lines of development. Actually a
57
-- forest in case of multiple projects, with one tree per
58
-- project.
59
60
sid INTEGER NOT NULL PRIMARY KEY REFERENCES symbol,
61
pid INTEGER NOT NULL REFERENCES symbol
62
} { pid }
63
# Index on: pid (branch successors)
64
return
65
}
66
67
typemethod load {} {
68
# Pass manager interface. Executed to load data computed by
69
# this pass into memory when this pass is skipped instead of
70
# executed.
71
72
# The results of this pass are fully in the persistent state,
73
# there is nothing to load for the next one.
74
return
75
}
76
77
typemethod run {} {
78
# Pass manager interface. Executed to perform the
79
# functionality of the pass.
80
81
state transaction {
82
repository determinesymboltypes
83
84
project::sym printrulestatistics
85
project::sym printtypestatistics
86
}
87
88
if {![trouble ?]} {
89
UnconvertedSymbols
90
BadSymbolTypes
91
BlockedExcludes
92
InvalidTags
93
}
94
95
if {![trouble ?]} {
96
DropExcludedSymbolsFromReferences
97
DeterminePreferedParents
98
}
99
100
log write 1 collsym "Collation completed"
101
return
102
}
103
104
typemethod discard {} {
105
# Pass manager interface. Executed for all passes after the
106
# run passes, to remove all data of this pass from the state,
107
# as being out of date.
108
109
state discard preferedparent
110
return
111
}
112
113
# # ## ### ##### ######## #############
114
## Internal methods
115
116
## TODO: Move UnconvertedSymbols, BadSymbolTypes, BlockedIncludes,
117
## TODO: InvalidTags to the integrity module?
118
119
proc UnconvertedSymbols {} {
120
# Paranoia - Have we left symbols without conversion
121
# information (i.e. with type 'undefined') ?
122
123
set undef [project::sym undef]
124
125
state foreachrow {
126
SELECT P.name AS pname, S.name AS sname
127
FROM symbol S, project P
128
WHERE S.type = $undef -- Restrict to undefined symbols
129
AND P.pid = S.pid -- Get project for symbol
130
} {
131
trouble fatal "$pname : The symbol '$sname' was left undefined"
132
}
133
return
134
}
135
136
proc BadSymbolTypes {} {
137
# Paranoia - Have we left symbols with bogus conversion
138
# information (type out of the valid range (excluded, branch,
139
# tag)) ?
140
141
state foreachrow {
142
SELECT P.name AS pname, S.name AS sname
143
FROM symbol S, project P
144
WHERE S.type NOT IN (0,1,2) -- Restrict to symbols with bogus type codes
145
AND P.pid = S.pid -- Get project of symbol
146
} {
147
trouble fatal "$pname : The symbol '$sname' has no proper conversion type"
148
}
149
return
150
}
151
152
proc BlockedExcludes {} {
153
# Paranoia - Have we scheduled symbols for exclusion without
154
# also excluding their dependent symbols ?
155
156
set excl [project::sym excluded]
157
158
state foreachrow {
159
SELECT P.name AS pname, S.name AS sname, SB.name AS bname
160
FROM symbol S, blocker B, symbol SB, project P
161
WHERE S.type = $excl -- Restrict to excluded symbols
162
AND S.sid = B.sid -- Get symbols blocking them
163
AND B.bid = SB.sid -- and
164
AND SB.type != $excl -- which are not excluded themselves
165
AND P.pid = S.pid -- Get project of symbol
166
} {
167
trouble fatal "$pname : The symbol '$sname' cannot be excluded as the unexcluded symbol '$bname' depends on it."
168
}
169
return
170
}
171
172
proc InvalidTags {} {
173
# Paranoia - Have we scheduled symbols for conversion as tags
174
# which absolutely cannot be converted as tags due to commits
175
# made on them ?
176
177
# In other words, this checks finds out if the user has asked
178
# nonsensical conversions of symbols, which should have been
179
# left to the heuristics, most specifically
180
# 'project::sym.HasCommits()'.
181
182
set tag [project::sym tag]
183
184
state foreachrow {
185
SELECT P.name AS pname, S.name AS sname
186
FROM project P, symbol S
187
WHERE S.type = $tag -- Restrict to tag symbols
188
AND S.commit_count > 0 -- which have revisions committed to them
189
AND P.pid = S.pid -- Get project of symbol
190
} {
191
trouble fatal "$pname : The symbol '$sname' cannot be forced to be converted as tag because it has commits."
192
}
193
return
194
}
195
196
proc DropExcludedSymbolsFromReferences {} {
197
# The excluded symbols cann be used as blockers nor as
198
# possible parent for other symbols. We now drop the relevant
199
# entries to prevent them from causing confusion later on.
200
201
set excl [project::sym excluded]
202
203
state run {
204
DELETE FROM blocker
205
WHERE bid IN (SELECT sid
206
FROM symbol
207
WhERE type = $excl); -- Get excluded symbols
208
DELETE FROM parent
209
WHERE pid IN (SELECT sid
210
FROM symbol
211
WhERE type = $excl); -- Get excluded symbols
212
}
213
return
214
}
215
216
proc DeterminePreferedParents {} {
217
array set prefered {}
218
219
set excl [project::sym excluded]
220
221
# Phase I: Pull the possible parents, using sorting to put the
222
# prefered parent of each symbol last among all
223
# candidates, allowing us get the prefered one by
224
# each candidate overwriting all previous
225
# selections. Note that we ignore excluded symbols,
226
# we do not care about their prefered parents and do
227
# not attempt to compute them.
228
229
state foreachrow {
230
SELECT S.sid AS xs,
231
P.pid AS xp,
232
S.name AS sname,
233
SB.name AS pname,
234
PR.name AS prname,
235
P.n AS votes
236
FROM symbol S, parent P, symbol SB, project PR
237
WHERE S.type != $excl -- Restrict to wanted symbols
238
AND S.sid = P.sid -- Get possible parents of symbol
239
AND P.pid = SB.sid -- and
240
AND S.pid = PR.pid -- the project of the symbol
241
ORDER BY P.n ASC, P.pid DESC -- Sorting, see below
242
--
243
-- Higher votes and smaller ids (= earlier branches) last
244
-- We simply keep the last possible parent for each
245
-- symbol. This parent will have the max number of votes
246
-- for its symbol and will be the earliest created branch
247
-- possible among all with many votes.
248
} {
249
log write 9 pcollsym "Voting $votes for Parent($sname) = $pname"
250
251
set prefered($xs) [list $xp $sname $pname $prname]
252
}
253
254
# Phase II: Write the found preferences back into the table
255
# this pass defined for it.
256
257
foreach {s x} [array get prefered] {
258
struct::list assign $x p sname pname prname
259
state run {
260
INSERT INTO preferedparent (sid, pid)
261
VALUES ($s, $p);
262
}
263
264
log write 3 pcollsym "$prname : '$sname's prefered parent is '$pname'"
265
}
266
267
# Phase III: Check the result that all symbols except for
268
# trunks have a prefered parent. We also ignore
269
# excluded symbols, as we intentionally did not
270
# compute a prefered parent for them, see phase I.
271
272
state foreachrow {
273
SELECT PR.name AS pname, S.name AS sname
274
FROM symbol S LEFT OUTER JOIN preferedparent P
275
ON S.sid = P.sid, -- From symbol to prefered parent
276
project PR
277
WHERE P.pid IS NULL -- restrict to symbols without a preference
278
AND S.type != $excl -- which are not excluded
279
AND S.name != ':trunk:' -- and are not a trunk
280
AND S.pid = PR.pid -- get project of symbol
281
} {
282
trouble fatal "$pname : '$sname' has no prefered parent."
283
}
284
285
# The reverse, having prefered parents for unknown symbols
286
# cannot occur.
287
return
288
}
289
290
# # ## ### ##### ######## #############
291
## Configuration
292
293
pragma -hasinstances no ; # singleton
294
pragma -hastypeinfo no ; # no introspection
295
pragma -hastypedestroy no ; # immortal
296
297
# # ## ### ##### ######## #############
298
}
299
300
namespace eval ::vc::fossil::import::cvs::pass {
301
namespace export collsym
302
namespace eval collsym {
303
namespace import ::vc::fossil::import::cvs::repository
304
namespace import ::vc::fossil::import::cvs::state
305
namespace eval project {
306
namespace import ::vc::fossil::import::cvs::project::sym
307
}
308
namespace import ::vc::tools::trouble
309
namespace import ::vc::tools::log
310
log register collsym
311
}
312
}
313
314
# # ## ### ##### ######## ############# #####################
315
## Ready
316
317
package provide vc::fossil::import::cvs::pass::collsym 1.0
318
return
319

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button