author | Claus Gittinger <cg@exept.de> |
Mon, 14 May 2018 02:21:18 +0200 | |
changeset 1048 | 582b3a028cbc |
parent 1037 | c0c1ac5fa4d5 |
permissions | -rw-r--r-- |
1037 | 1 |
"{ Encoding: utf8 }" |
2 |
||
70 | 3 |
"{ Package: 'stx:goodies/monticello' }" |
4 |
||
1037 | 5 |
"{ NameSpace: Smalltalk }" |
6 |
||
70 | 7 |
Object subclass:#MCPackageLoader |
213 | 8 |
instanceVariableNames:'requirements unloadableDefinitions overrideDefinitions |
9 |
obsoletions additions removals errorDefinitions provisions' |
|
430 | 10 |
classVariableNames:'Debugging' |
70 | 11 |
poolDictionaries:'' |
663 | 12 |
category:'SCM-Monticello-Loading' |
70 | 13 |
! |
14 |
||
15 |
||
213 | 16 |
!MCPackageLoader class methodsFor:'initialization'! |
17 |
||
18 |
new |
|
19 |
^self basicNew initialize |
|
20 |
! ! |
|
21 |
||
70 | 22 |
!MCPackageLoader class methodsFor:'as yet unclassified'! |
23 |
||
24 |
installSnapshot: aSnapshot |
|
25 |
self new |
|
26 |
installSnapshot: aSnapshot; |
|
27 |
load |
|
28 |
! |
|
29 |
||
30 |
unloadPackage: aPackage |
|
31 |
self new |
|
32 |
unloadPackage: aPackage; |
|
33 |
loadWithNameLike: aPackage name, '-unload' |
|
34 |
! |
|
35 |
||
36 |
updatePackage: aPackage withSnapshot: aSnapshot |
|
37 |
self new |
|
38 |
updatePackage: aPackage withSnapshot: aSnapshot; |
|
39 |
load |
|
40 |
! ! |
|
41 |
||
213 | 42 |
!MCPackageLoader methodsFor:'accessing'! |
43 |
||
44 |
overrideDefinitions |
|
45 |
^ overrideDefinitions |
|
46 |
! |
|
47 |
||
48 |
unloadableDefinitions |
|
49 |
^ unloadableDefinitions |
|
50 |
! ! |
|
51 |
||
70 | 52 |
!MCPackageLoader methodsFor:'patch ops'! |
53 |
||
54 |
addDefinition: aDefinition |
|
55 |
additions add: aDefinition |
|
56 |
! |
|
57 |
||
58 |
modifyDefinition: old to: new |
|
59 |
self addDefinition: new. |
|
60 |
obsoletions at: new put: old. |
|
61 |
! |
|
62 |
||
63 |
removeDefinition: aDefinition |
|
64 |
removals add: aDefinition |
|
65 |
! ! |
|
66 |
||
67 |
!MCPackageLoader methodsFor:'private'! |
|
68 |
||
69 |
analyze |
|
213 | 70 |
| sorter | |
71 |
sorter := self sorterForItems: additions. |
|
72 |
additions := sorter orderedItems. |
|
73 |
requirements := sorter externalRequirements. |
|
74 |
unloadableDefinitions := sorter itemsWithMissingRequirements asSortedCollection. |
|
75 |
||
76 |
overrideDefinitions := additions select:[:e|e isOverrideDefinition]. |
|
77 |
additions := additions reject: [:e|e isOverrideDefinition]. |
|
78 |
||
79 |
sorter := self sorterForItems: removals. |
|
80 |
removals := sorter orderedItems reversed. |
|
81 |
||
82 |
"Modified: / 08-11-2010 / 17:34:38 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
70 | 83 |
! |
84 |
||
85 |
basicLoad |
|
213 | 86 |
| allowEmptyStatements allowSqueakExtensions | |
87 |
||
88 |
allowEmptyStatements := ParserFlags allowEmptyStatements. |
|
89 |
allowSqueakExtensions := ParserFlags allowSqueakExtensions. |
|
90 |
ParserFlags allowEmptyStatements: true. |
|
91 |
ParserFlags allowSqueakExtensions: true. |
|
92 |
||
93 |
errorDefinitions := OrderedCollection new. |
|
94 |
self warnAboutUnloadables. |
|
95 |
||
96 |
||
97 |
[[ |
|
98 |
| oldErrorDefinitions | |
|
99 |
additions do: [:ea | self tryToLoad: ea] displayingProgress: 'Loading...'. |
|
100 |
removals do: [:ea | ea unload] displayingProgress: 'Cleaning up...'. |
|
101 |
self shouldWarnAboutErrors ifTrue: [self warnAboutErrors]. |
|
102 |
oldErrorDefinitions := errorDefinitions. |
|
103 |
errorDefinitions := OrderedCollection new. |
|
104 |
oldErrorDefinitions do: [:ea | self tryToLoad: ea] displayingProgress: 'Reloading...'. |
|
105 |
additions do: [:ea | ea postloadOver: (self obsoletionFor: ea)] displayingProgress: 'Initializing...'. |
|
106 |
||
107 |
self warnAboutOverrides. |
|
108 |
self warnAboutErrors. |
|
109 |
||
110 |
] |
|
111 |
||
112 |
on: InMidstOfFileinNotification |
|
113 |
do: [:n | n resume: true]] |
|
114 |
ensure: |
|
115 |
[self flushChangesFile. |
|
116 |
ParserFlags allowEmptyStatements: allowEmptyStatements. |
|
117 |
ParserFlags allowSqueakExtensions: allowSqueakExtensions. |
|
118 |
] |
|
119 |
||
120 |
"Modified: / 08-11-2010 / 23:49:38 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
430 | 121 |
"Modified: / 20-08-2011 / 18:20:54 / cg" |
70 | 122 |
! |
123 |
||
124 |
dependencyWarning |
|
125 |
^ String streamContents: |
|
126 |
[:s | |
|
127 |
s nextPutAll: 'This package depends on the following classes:'; cr. |
|
128 |
requirements do: [:ea | s space; space; nextPutAll: ea; cr]. |
|
129 |
s nextPutAll: 'You must resolve these dependencies before you will be able to load these definitions: '; cr. |
|
130 |
unloadableDefinitions do: [:ea | s space; space; nextPutAll: ea summary; cr]] |
|
131 |
! |
|
132 |
||
133 |
errorDefinitionWarning |
|
134 |
^ String streamContents: |
|
135 |
[:s | |
|
136 |
s nextPutAll: 'The following definitions had errors while loading. Press Proceed to try to load them again (they may work on a second pass):'; cr. |
|
137 |
errorDefinitions do: [:ea | s space; space; nextPutAll: ea summary; cr]] |
|
138 |
! |
|
139 |
||
140 |
flushChangesFile |
|
213 | 141 |
"The changes file is second in the SourceFiles array" |
142 |
||
143 |
"(SourceFiles at: 2) flush" |
|
144 |
||
145 |
"Modified: / 11-09-2010 / 18:32:03 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
146 |
! |
|
147 |
||
148 |
ifInteractive: aBlock |
|
149 |
||
150 |
^self ifInteractive: aBlock else:[] |
|
70 | 151 |
|
213 | 152 |
"Created: / 06-03-2011 / 20:32:00 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
153 |
! |
|
154 |
||
155 |
ifInteractive: interactiveBlock else: noninteractiveBlock |
|
156 |
||
157 |
MCInteractiveLoadingQuery query |
|
158 |
ifTrue:[interactiveBlock value] |
|
159 |
ifFalse:[noninteractiveBlock value]. |
|
160 |
||
161 |
"Created: / 06-03-2011 / 20:31:29 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
70 | 162 |
! |
163 |
||
164 |
initialize |
|
213 | 165 |
super initialize. |
166 |
additions := OrderedCollection new. |
|
167 |
removals := OrderedCollection new. |
|
168 |
obsoletions := Dictionary new. |
|
169 |
||
70 | 170 |
! |
171 |
||
172 |
obsoletionFor: aDefinition |
|
173 |
^ obsoletions at: aDefinition ifAbsent: [nil] |
|
174 |
! |
|
175 |
||
176 |
orderDefinitionsForLoading: aCollection |
|
177 |
^ (self sorterForItems: aCollection) orderedItems |
|
178 |
! |
|
179 |
||
180 |
orderedAdditions |
|
181 |
^ additions |
|
182 |
! |
|
183 |
||
184 |
provisions |
|
213 | 185 |
^ provisions ifNil: [provisions := Set withAll: Smalltalk keys] |
70 | 186 |
! |
187 |
||
188 |
shouldWarnAboutErrors |
|
189 |
^ errorDefinitions isEmpty not and: [false "should make this a preference"] |
|
190 |
! |
|
191 |
||
192 |
sorterForItems: aCollection |
|
193 |
| sorter | |
|
213 | 194 |
sorter := MCDependencySorter items: aCollection. |
70 | 195 |
sorter addExternalProvisions: self provisions. |
196 |
^ sorter |
|
197 |
! |
|
198 |
||
199 |
tryToLoad: aDefinition |
|
430 | 200 |
[aDefinition loadOver: (self obsoletionFor: aDefinition)] on: Error do: [:ex | |
663 | 201 |
errorDefinitions add: aDefinition. |
202 |
||
430 | 203 |
Debugging == true ifTrue:[ |
204 |
ex reject |
|
205 |
]. |
|
206 |
Transcript showCR:'error during load (to debug, set MCPackageLoader:Debugging to true): '. |
|
207 |
Transcript showCR:ex description. |
|
208 |
]. |
|
209 |
||
663 | 210 |
"Modified: / 11-09-2012 / 09:55:23 / cg" |
70 | 211 |
! |
212 |
||
213 | 213 |
tryToLoadAll: definitions label: label |
214 |
||
215 |
definitions do:[:e|self tryToLoad: e] displayingProgress: label. |
|
216 |
||
217 |
"Created: / 09-11-2010 / 17:17:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
218 |
! |
|
219 |
||
70 | 220 |
useChangeSetNamed: baseName during: aBlock |
213 | 221 |
"Use the named change set, or create one with the given name." |
940 | 222 |
| changeHolder oldChanges "newChanges" | |
223 |
||
213 | 224 |
changeHolder := (ChangeSet respondsTo: #newChanges:) |
225 |
ifTrue: [ChangeSet] |
|
226 |
ifFalse: [Smalltalk]. |
|
227 |
oldChanges := (ChangeSet respondsTo: #current) |
|
228 |
ifTrue: [ChangeSet current] |
|
229 |
ifFalse: [Smalltalk changes]. |
|
70 | 230 |
|
467
6485629d7afe
changed: #useChangeSetNamed:during:
Claus Gittinger <cg@exept.de>
parents:
433
diff
changeset
|
231 |
"/JV @ 2010-09-11: Don't care about changes |
213 | 232 |
"/newChanges := (ChangeSorter changeSetNamed: baseName) ifNil: [ ChangeSet new name: baseName ]. |
233 |
"/changeHolder newChanges: newChanges. |
|
234 |
"/[aBlock value] ensure: [changeHolder newChanges: oldChanges]. |
|
467
6485629d7afe
changed: #useChangeSetNamed:during:
Claus Gittinger <cg@exept.de>
parents:
433
diff
changeset
|
235 |
"/ Class withoutUpdatingChangesDo: aBlock |
6485629d7afe
changed: #useChangeSetNamed:during:
Claus Gittinger <cg@exept.de>
parents:
433
diff
changeset
|
236 |
aBlock value. |
213 | 237 |
|
238 |
"Modified: / 08-11-2010 / 20:01:04 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
467
6485629d7afe
changed: #useChangeSetNamed:during:
Claus Gittinger <cg@exept.de>
parents:
433
diff
changeset
|
239 |
"Modified: / 05-09-2011 / 15:56:36 / cg" |
70 | 240 |
! |
241 |
||
242 |
useNewChangeSetDuring: aBlock |
|
243 |
^self useNewChangeSetNamedLike: 'MC' during: aBlock |
|
244 |
! |
|
245 |
||
246 |
useNewChangeSetNamedLike: baseName during: aBlock |
|
247 |
^self useChangeSetNamed: (ChangeSet uniqueNameLike: baseName) during: aBlock |
|
248 |
! |
|
249 |
||
213 | 250 |
warnAboutDependencies |
251 |
" |
|
252 |
||
253 |
||
254 |
self notify: self dependencyWarning |
|
255 |
" |
|
256 |
||
257 |
"Modified: / 13-10-2010 / 15:44:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
70 | 258 |
! |
259 |
||
260 |
warnAboutErrors |
|
213 | 261 |
|
262 |
| changes | |
|
263 |
||
264 |
errorDefinitions isNilOrEmptyCollection ifTrue:[^self]. |
|
1037 | 265 |
changes := ChangeSet new. |
266 |
errorDefinitions select:[:e|e notNil] thenDo:[:e|e addChangesTo:changes]. |
|
213 | 267 |
|
430 | 268 |
changes := Tools::ChangeSetBrowser2 |
213 | 269 |
openOn: changes |
270 |
label:'Error definitions'. |
|
271 |
||
272 |
"Created: / 08-11-2010 / 20:19:24 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
273 |
"Modified: / 06-03-2011 / 20:39:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
430 | 274 |
"Modified: / 20-08-2011 / 18:00:02 / cg" |
213 | 275 |
! |
276 |
||
277 |
warnAboutOverrides |
|
278 |
||
431 | 279 |
| changes confirmedChanges definitions | |
213 | 280 |
|
281 |
overrideDefinitions isNilOrEmptyCollection ifTrue:[^self]. |
|
282 |
self ifInteractive:[ |
|
1037 | 283 |
changes := ChangeSet new. |
284 |
overrideDefinitions do:[:e|e addChangesTo:changes]. |
|
431 | 285 |
self assert:(changes includes:nil) not. |
1037 | 286 |
|
431 | 287 |
confirmedChanges := Tools::ChangeSetBrowser2 |
213 | 288 |
confirmChanges: changes |
289 |
label:'Overridden definitions. Load anyway?'. |
|
433 | 290 |
confirmedChanges notEmpty ifTrue:[ |
291 |
confirmedChanges := confirmedChanges flatten. |
|
1037 | 292 |
definitions := confirmedChanges collect:[:e|e mcDefinition] thenSelect:[:e | e notNil]. |
293 |
"/ we might get nil in a roundTrip |
|
294 |
"/ (eg. for mcDef --addChangesTo:--> classChange+commentChange --mcDefinition--> mcDef+nil) |
|
295 |
"/ self assert:(definitions includes:nil) not. |
|
296 |
||
433 | 297 |
self tryToLoadAll: definitions label: 'Loading overrides...'. |
298 |
] |
|
213 | 299 |
] else:[ |
300 |
self tryToLoadAll: overrideDefinitions label: 'Loading overrides...'. |
|
301 |
] |
|
302 |
||
303 |
"Created: / 08-11-2010 / 20:19:24 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
304 |
"Modified: / 06-03-2011 / 20:33:25 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
433 | 305 |
"Modified: / 20-08-2011 / 19:31:40 / cg" |
213 | 306 |
! |
307 |
||
308 |
warnAboutUnloadables |
|
309 |
||
433 | 310 |
| changes confirmedChanges definitions | |
213 | 311 |
|
312 |
unloadableDefinitions isNilOrEmptyCollection ifTrue:[^self]. |
|
313 |
self ifInteractive:[ |
|
1037 | 314 |
changes := ChangeSet new. |
315 |
unloadableDefinitions do:[:e|e addChangesTo:changes]. |
|
431 | 316 |
self assert:(changes includes:nil) not. |
1037 | 317 |
|
433 | 318 |
confirmedChanges := Tools::ChangeSetBrowser2 |
213 | 319 |
confirmChanges: changes |
320 |
label:'Unsatisfied dependencies. Load anyway?'. |
|
433 | 321 |
confirmedChanges notEmpty ifTrue:[ |
322 |
confirmedChanges := confirmedChanges flatten. |
|
1037 | 323 |
definitions := confirmedChanges collect:[:e|e mcDefinition] thenSelect:[:e | e notNil]. |
324 |
"/ we might get nil in a roundTrip |
|
325 |
"/ (eg. for mcDef --addChangesTo:--> classChange+commentChange --mcDefinition--> mcDef+nil) |
|
326 |
"/ self assert:(definitions includes:nil) not. |
|
327 |
||
433 | 328 |
self tryToLoadAll: definitions label: 'Loading unloadables...'. |
329 |
] |
|
213 | 330 |
] else:[ |
331 |
self tryToLoadAll: unloadableDefinitions label: 'Loading unloadables...'. |
|
332 |
] |
|
333 |
||
334 |
"Created: / 08-11-2010 / 20:19:24 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
335 |
"Modified: / 06-03-2011 / 20:36:11 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
433 | 336 |
"Modified: / 20-08-2011 / 19:31:22 / cg" |
70 | 337 |
! ! |
338 |
||
339 |
!MCPackageLoader methodsFor:'public'! |
|
340 |
||
341 |
installSnapshot: aSnapshot |
|
342 |
| patch | |
|
213 | 343 |
patch := aSnapshot patchRelativeToBase: MCSnapshot empty. |
70 | 344 |
patch applyTo: self. |
213 | 345 |
|
70 | 346 |
! |
347 |
||
348 |
load |
|
349 |
self analyze. |
|
350 |
unloadableDefinitions isEmpty ifFalse: [self warnAboutDependencies]. |
|
351 |
self useNewChangeSetDuring: [self basicLoad] |
|
352 |
! |
|
353 |
||
354 |
loadWithName: baseName |
|
355 |
self analyze. |
|
356 |
unloadableDefinitions isEmpty ifFalse: [self warnAboutDependencies]. |
|
357 |
self useChangeSetNamed: baseName during: [self basicLoad] |
|
358 |
! |
|
359 |
||
360 |
loadWithNameLike: baseName |
|
361 |
self analyze. |
|
362 |
unloadableDefinitions isEmpty ifFalse: [self warnAboutDependencies]. |
|
363 |
self useNewChangeSetNamedLike: baseName during: [self basicLoad] |
|
364 |
! |
|
365 |
||
366 |
unloadPackage: aPackage |
|
367 |
self updatePackage: aPackage withSnapshot: MCSnapshot empty |
|
368 |
! |
|
369 |
||
370 |
updatePackage: aPackage withSnapshot: aSnapshot |
|
213 | 371 |
| patch packageSnap | |
469
fa3b9dc54085
comment/format in: #updatePackage:withSnapshot:
Claus Gittinger <cg@exept.de>
parents:
467
diff
changeset
|
372 |
|
fa3b9dc54085
comment/format in: #updatePackage:withSnapshot:
Claus Gittinger <cg@exept.de>
parents:
467
diff
changeset
|
373 |
MCStXPackageQuery |
fa3b9dc54085
comment/format in: #updatePackage:withSnapshot:
Claus Gittinger <cg@exept.de>
parents:
467
diff
changeset
|
374 |
answer: aPackage name |
fa3b9dc54085
comment/format in: #updatePackage:withSnapshot:
Claus Gittinger <cg@exept.de>
parents:
467
diff
changeset
|
375 |
do:[ |
fa3b9dc54085
comment/format in: #updatePackage:withSnapshot:
Claus Gittinger <cg@exept.de>
parents:
467
diff
changeset
|
376 |
packageSnap := aPackage snapshot. |
fa3b9dc54085
comment/format in: #updatePackage:withSnapshot:
Claus Gittinger <cg@exept.de>
parents:
467
diff
changeset
|
377 |
patch := aSnapshot patchRelativeToBase: packageSnap. |
fa3b9dc54085
comment/format in: #updatePackage:withSnapshot:
Claus Gittinger <cg@exept.de>
parents:
467
diff
changeset
|
378 |
patch applyTo: self. |
fa3b9dc54085
comment/format in: #updatePackage:withSnapshot:
Claus Gittinger <cg@exept.de>
parents:
467
diff
changeset
|
379 |
packageSnap definitions do: [:ea | self provisions addAll: ea provisions] |
fa3b9dc54085
comment/format in: #updatePackage:withSnapshot:
Claus Gittinger <cg@exept.de>
parents:
467
diff
changeset
|
380 |
] |
213 | 381 |
|
382 |
"Modified: / 14-09-2010 / 22:09:54 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
469
fa3b9dc54085
comment/format in: #updatePackage:withSnapshot:
Claus Gittinger <cg@exept.de>
parents:
467
diff
changeset
|
383 |
"Modified (format): / 07-09-2011 / 12:44:16 / cg" |
70 | 384 |
! ! |
385 |
||
386 |
!MCPackageLoader class methodsFor:'documentation'! |
|
387 |
||
388 |
version |
|
1037 | 389 |
^ '$Header$' |
213 | 390 |
! |
391 |
||
392 |
version_CVS |
|
1037 | 393 |
^ '$Header$' |
213 | 394 |
! |
395 |
||
396 |
version_SVN |
|
1037 | 397 |
^ '$Id$' |
70 | 398 |
! ! |
940 | 399 |