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