Frank Shearar uploaded a new version of CommandLine to project The Trunk:
http://source.squeak.org/trunk/CommandLine-fbs.1.mcz ==================== Summary ==================== Name: CommandLine-fbs.1 Author: fbs Time: 31 October 2013, 10:32:52.821 pm UUID: dc871e85-bd16-d742-acbf-4d2b838113d1 Ancestors: CommandLineToolSet does little more than dump errors to stderr. DummyUIManager comes from Pharo via Pavel Krivanek's minimising script. ==================== Snapshot ==================== SystemOrganization addCategory: #'CommandLine-Tools'! SystemOrganization addCategory: #'CommandLine-UIManager'! UIManager subclass: #DummyUIManager instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CommandLine-UIManager'! !DummyUIManager commentStamp: 'fbs 10/31/2013 07:36' prior: 0! I'm an alternative UIManager used to run an the image without GUI. I redefine methods which require user input as these requests are irrelevant in a headless environment. ! ----- Method: DummyUIManager>>checkForNewDisplaySize (in category 'display') ----- checkForNewDisplaySize Display extent = DisplayScreen actualScreenSize ifTrue: [^ self]. DisplayScreen startUp. ! ----- Method: DummyUIManager>>chooseDirectory:from: (in category 'ui requests') ----- chooseDirectory: label from: dir ^ nil! ----- Method: DummyUIManager>>chooseFrom:lines:title: (in category 'ui requests') ----- chooseFrom: aList lines: linesArray title: aString ^ aList first! ----- Method: DummyUIManager>>chooseFrom:values:lines:title: (in category 'ui requests') ----- chooseFrom: labelList values: valueList lines: linesArray title: aString ^ valueList first! ----- Method: DummyUIManager>>confirm: (in category 'ui requests') ----- confirm: queryString (ProvideAnswerNotification signal: queryString) ifNotNil: [:answer|^answer]. self error: 'No user response possible'! ----- Method: DummyUIManager>>confirm:orCancel: (in category 'ui requests') ----- confirm: aString orCancel: cancelBlock (ProvideAnswerNotification signal: aString) ifNotNil: [:answer | ^answer == #cancel ifTrue: [cancelBlock value] ifFalse: [answer]]. self error: 'No user response possible'! ----- Method: DummyUIManager>>displayProgress:at:from:to:during: (in category 'ui requests') ----- displayProgress: titleString at: aPoint from: minVal to: maxVal during: workBlock ^ workBlock value: Association new! ----- Method: DummyUIManager>>edit:label:accept: (in category 'ui requests') ----- edit: aText label: labelString accept: anAction ^ nil! ----- Method: DummyUIManager>>fontFromUser: (in category 'ui requests') ----- fontFromUser: priorFont self error: 'No user response possible'! ----- Method: DummyUIManager>>inform: (in category 'ui requests') ----- inform: aString "Nothing to be done here"! ----- Method: DummyUIManager>>informUserDuring: (in category 'ui requests') ----- informUserDuring: aBlock aBlock value: nil! ----- Method: DummyUIManager>>newDisplayDepthNoRestore: (in category 'display') ----- newDisplayDepthNoRestore: pixelSize "Change depths. Check if there is enough space!! , di" | area need | pixelSize = Display depth ifTrue: [^ self "no change"]. pixelSize abs < Display depth ifFalse: ["Make sure there is enough space" area := Display boundingBox area. "pixels" need := (area * (pixelSize abs - Display depth) // 8) "new bytes needed" + Smalltalk lowSpaceThreshold. (Smalltalk garbageCollectMost <= need and: [Smalltalk garbageCollect <= need]) ifTrue: [self error: 'Insufficient free space']]. Display setExtent: Display extent depth: pixelSize. DisplayScreen startUp! ----- Method: DummyUIManager>>request:initialAnswer: (in category 'ui requests') ----- request: queryString initialAnswer: defaultAnswer (ProvideAnswerNotification signal: queryString) ifNotNil: [:answer | ^ answer == #default ifTrue: [defaultAnswer] ifFalse: [answer]]. self error: 'No user response possible'! ----- Method: DummyUIManager>>requestPassword: (in category 'ui requests') ----- requestPassword: queryString ^ self request: queryString initialAnswer: ''! ----- Method: DummyUIManager>>restoreDisplay (in category 'display') ----- restoreDisplay! ----- Method: DummyUIManager>>restoreDisplayAfter: (in category 'display') ----- restoreDisplayAfter: aBlock aBlock value. Sensor waitButton.! StandardToolSet subclass: #CommandLineToolSet instanceVariableNames: '' classVariableNames: 'SaveSnapshotOnError' poolDictionaries: '' category: 'CommandLine-Tools'! ----- Method: CommandLineToolSet class>>debugError: (in category 'debugging') ----- debugError: anError "Print out a sensible stack trace and bail" | problemPlace s | self saveSnapshotOnError ifTrue: [Smalltalk saveAs: 'Debug-' , (Smalltalk imageName subStrings: '/') last]. problemPlace := anError signalerContext. s := FileStream stderr. (anError isKindOf: MessageNotUnderstood) ifTrue: [ s nextPutAll: anError messageText; cr; nextPutAll: problemPlace sender methodNode printString; cr]. (problemPlace stackOfSize: 20) do: [:ctx | s cr. ctx printOn: s]. s flush. SmalltalkImage current snapshot: false andQuit: true! ----- Method: CommandLineToolSet class>>debugSyntaxError: (in category 'debugging') ----- debugSyntaxError: anError | s | s := FileStream stderr. s nextPutAll: '----- Syntax error -----'; cr. s nextPutAll: anError errorCode; cr. s nextPutAll: '----- Syntax error -----'; cr. self debugError: anError! ----- Method: CommandLineToolSet class>>saveSnapshotOnError (in category 'preferences') ----- saveSnapshotOnError <preference: 'Save snapshot of image on failure' category: 'debug' description: 'If true, saves a snapshot of the failing image to the current directory.' type: #Boolean> ^ SaveSnapshotOnError ifNil: [SaveSnapshotOnError := false].! ----- Method: CommandLineToolSet class>>saveSnapshotOnError: (in category 'preferences') ----- saveSnapshotOnError: aBoolean SaveSnapshotOnError := aBoolean.! ----- Method: CommandLineToolSet class>>unload (in category 'class initialization') ----- unload ToolSet unregister: self.! |
+1, please include in the update.mcm! I also like the Pharo alternative to Fuel out the error context... Lighter than full image save. Oh but we don't have Fuel yet :( Who wants to make it with a segment? 2013/10/31 <[hidden email]> Frank Shearar uploaded a new version of CommandLine to project The Trunk: |
Fuel works in 4.4, but not quite yet in 4.5:
http://build.squeak.org/job/ExternalPackage-Fuel/lastFailedBuild/console Sadly, that output's not particularly useful. frank On 31 October 2013 23:02, Nicolas Cellier <[hidden email]> wrote: > +1, please include in the update.mcm! > I also like the Pharo alternative to Fuel out the error context... > Lighter than full image save. Oh but we don't have Fuel yet :( > Who wants to make it with a segment? > > > 2013/10/31 <[hidden email]> > >> Frank Shearar uploaded a new version of CommandLine to project The Trunk: >> http://source.squeak.org/trunk/CommandLine-fbs.1.mcz >> >> ==================== Summary ==================== >> >> Name: CommandLine-fbs.1 >> Author: fbs >> Time: 31 October 2013, 10:32:52.821 pm >> UUID: dc871e85-bd16-d742-acbf-4d2b838113d1 >> Ancestors: >> >> CommandLineToolSet does little more than dump errors to stderr. >> >> DummyUIManager comes from Pharo via Pavel Krivanek's minimising script. >> >> ==================== Snapshot ==================== >> >> SystemOrganization addCategory: #'CommandLine-Tools'! >> SystemOrganization addCategory: #'CommandLine-UIManager'! >> >> UIManager subclass: #DummyUIManager >> instanceVariableNames: '' >> classVariableNames: '' >> poolDictionaries: '' >> category: 'CommandLine-UIManager'! >> >> !DummyUIManager commentStamp: 'fbs 10/31/2013 07:36' prior: 0! >> I'm an alternative UIManager used to run an the image without GUI. I >> redefine methods which require user input as these requests are irrelevant >> in a headless environment. ! >> >> ----- Method: DummyUIManager>>checkForNewDisplaySize (in category >> 'display') ----- >> checkForNewDisplaySize >> Display extent = DisplayScreen actualScreenSize ifTrue: [^ self]. >> DisplayScreen startUp. >> ! >> >> ----- Method: DummyUIManager>>chooseDirectory:from: (in category 'ui >> requests') ----- >> chooseDirectory: label from: dir >> ^ nil! >> >> ----- Method: DummyUIManager>>chooseFrom:lines:title: (in category 'ui >> requests') ----- >> chooseFrom: aList lines: linesArray title: aString >> ^ aList first! >> >> ----- Method: DummyUIManager>>chooseFrom:values:lines:title: (in category >> 'ui requests') ----- >> chooseFrom: labelList values: valueList lines: linesArray title: aString >> ^ valueList first! >> >> ----- Method: DummyUIManager>>confirm: (in category 'ui requests') ----- >> confirm: queryString >> (ProvideAnswerNotification signal: queryString) >> ifNotNil: [:answer|^answer]. >> >> self error: 'No user response possible'! >> >> ----- Method: DummyUIManager>>confirm:orCancel: (in category 'ui >> requests') ----- >> confirm: aString orCancel: cancelBlock >> (ProvideAnswerNotification signal: aString) ifNotNil: [:answer | >> ^answer == #cancel ifTrue: [cancelBlock value] ifFalse: [answer]]. >> >> self error: 'No user response possible'! >> >> ----- Method: DummyUIManager>>displayProgress:at:from:to:during: (in >> category 'ui requests') ----- >> displayProgress: titleString at: aPoint from: minVal to: maxVal during: >> workBlock >> ^ workBlock value: Association new! >> >> ----- Method: DummyUIManager>>edit:label:accept: (in category 'ui >> requests') ----- >> edit: aText label: labelString accept: anAction >> ^ nil! >> >> ----- Method: DummyUIManager>>fontFromUser: (in category 'ui requests') >> ----- >> fontFromUser: priorFont >> self error: 'No user response possible'! >> >> ----- Method: DummyUIManager>>inform: (in category 'ui requests') ----- >> inform: aString >> "Nothing to be done here"! >> >> ----- Method: DummyUIManager>>informUserDuring: (in category 'ui >> requests') ----- >> informUserDuring: aBlock >> aBlock value: nil! >> >> ----- Method: DummyUIManager>>newDisplayDepthNoRestore: (in category >> 'display') ----- >> newDisplayDepthNoRestore: pixelSize >> "Change depths. Check if there is enough space!! , di" >> | area need | >> pixelSize = Display depth ifTrue: [^ self "no change"]. >> pixelSize abs < Display depth ifFalse: >> ["Make sure there is enough space" >> area := Display boundingBox area. "pixels" >> >> need := (area * (pixelSize abs - Display depth) // 8) >> "new bytes needed" >> + Smalltalk lowSpaceThreshold. >> (Smalltalk garbageCollectMost <= need >> and: [Smalltalk garbageCollect <= need]) >> ifTrue: [self error: 'Insufficient free space']]. >> Display setExtent: Display extent depth: pixelSize. >> >> DisplayScreen startUp! >> >> ----- Method: DummyUIManager>>request:initialAnswer: (in category 'ui >> requests') ----- >> request: queryString initialAnswer: defaultAnswer >> (ProvideAnswerNotification signal: queryString) >> ifNotNil: [:answer | >> ^ answer == #default ifTrue: [defaultAnswer] ifFalse: >> [answer]]. >> >> self error: 'No user response possible'! >> >> ----- Method: DummyUIManager>>requestPassword: (in category 'ui requests') >> ----- >> requestPassword: queryString >> ^ self request: queryString initialAnswer: ''! >> >> ----- Method: DummyUIManager>>restoreDisplay (in category 'display') ----- >> restoreDisplay! >> >> ----- Method: DummyUIManager>>restoreDisplayAfter: (in category 'display') >> ----- >> restoreDisplayAfter: aBlock >> aBlock value. >> Sensor waitButton.! >> >> StandardToolSet subclass: #CommandLineToolSet >> instanceVariableNames: '' >> classVariableNames: 'SaveSnapshotOnError' >> poolDictionaries: '' >> category: 'CommandLine-Tools'! >> >> ----- Method: CommandLineToolSet class>>debugError: (in category >> 'debugging') ----- >> debugError: anError >> "Print out a sensible stack trace and bail" >> | problemPlace s | >> self saveSnapshotOnError >> ifTrue: [Smalltalk saveAs: 'Debug-' , (Smalltalk imageName >> subStrings: '/') last]. >> problemPlace := anError signalerContext. >> s := FileStream stderr. >> (anError isKindOf: MessageNotUnderstood) ifTrue: [ >> s >> nextPutAll: anError messageText; cr; >> nextPutAll: problemPlace sender methodNode >> printString; cr]. >> (problemPlace stackOfSize: 20) do: [:ctx | s cr. ctx printOn: s]. >> s flush. >> >> SmalltalkImage current snapshot: false andQuit: true! >> >> ----- Method: CommandLineToolSet class>>debugSyntaxError: (in category >> 'debugging') ----- >> debugSyntaxError: anError >> | s | >> s := FileStream stderr. >> s nextPutAll: '----- Syntax error -----'; cr. >> s nextPutAll: anError errorCode; cr. >> s nextPutAll: '----- Syntax error -----'; cr. >> >> self debugError: anError! >> >> ----- Method: CommandLineToolSet class>>saveSnapshotOnError (in category >> 'preferences') ----- >> saveSnapshotOnError >> <preference: 'Save snapshot of image on failure' >> category: 'debug' >> description: 'If true, saves a snapshot of the failing image to >> the current directory.' >> type: #Boolean> >> ^ SaveSnapshotOnError ifNil: [SaveSnapshotOnError := false].! >> >> ----- Method: CommandLineToolSet class>>saveSnapshotOnError: (in category >> 'preferences') ----- >> saveSnapshotOnError: aBoolean >> SaveSnapshotOnError := aBoolean.! >> >> ----- Method: CommandLineToolSet class>>unload (in category 'class >> initialization') ----- >> unload >> ToolSet unregister: self.! >> >> > > > > |
Ah, but I see that you use SqueakMap... SqueakMap point to ConfigurationOfFuel-MartinDias.197That's a few hurdles, but we can make it. 2013/11/1 Frank Shearar <[hidden email]> Fuel works in 4.4, but not quite yet in 4.5: |
In reply to this post by Nicolas Cellier
We don't need to create a dependency on Fuel for that. Besides, it's
so much simpler to just _launch_ the image with the error, not get into another image and "load" it... On Thu, Oct 31, 2013 at 6:02 PM, Nicolas Cellier <[hidden email]> wrote: > +1, please include in the update.mcm! > I also like the Pharo alternative to Fuel out the error context... > Lighter than full image save. Oh but we don't have Fuel yet :( > Who wants to make it with a segment? > > > 2013/10/31 <[hidden email]> > >> Frank Shearar uploaded a new version of CommandLine to project The Trunk: >> http://source.squeak.org/trunk/CommandLine-fbs.1.mcz >> >> ==================== Summary ==================== >> >> Name: CommandLine-fbs.1 >> Author: fbs >> Time: 31 October 2013, 10:32:52.821 pm >> UUID: dc871e85-bd16-d742-acbf-4d2b838113d1 >> Ancestors: >> >> CommandLineToolSet does little more than dump errors to stderr. >> >> DummyUIManager comes from Pharo via Pavel Krivanek's minimising script. >> >> ==================== Snapshot ==================== >> >> SystemOrganization addCategory: #'CommandLine-Tools'! >> SystemOrganization addCategory: #'CommandLine-UIManager'! >> >> UIManager subclass: #DummyUIManager >> instanceVariableNames: '' >> classVariableNames: '' >> poolDictionaries: '' >> category: 'CommandLine-UIManager'! >> >> !DummyUIManager commentStamp: 'fbs 10/31/2013 07:36' prior: 0! >> I'm an alternative UIManager used to run an the image without GUI. I >> redefine methods which require user input as these requests are irrelevant >> in a headless environment. ! >> >> ----- Method: DummyUIManager>>checkForNewDisplaySize (in category >> 'display') ----- >> checkForNewDisplaySize >> Display extent = DisplayScreen actualScreenSize ifTrue: [^ self]. >> DisplayScreen startUp. >> ! >> >> ----- Method: DummyUIManager>>chooseDirectory:from: (in category 'ui >> requests') ----- >> chooseDirectory: label from: dir >> ^ nil! >> >> ----- Method: DummyUIManager>>chooseFrom:lines:title: (in category 'ui >> requests') ----- >> chooseFrom: aList lines: linesArray title: aString >> ^ aList first! >> >> ----- Method: DummyUIManager>>chooseFrom:values:lines:title: (in category >> 'ui requests') ----- >> chooseFrom: labelList values: valueList lines: linesArray title: aString >> ^ valueList first! >> >> ----- Method: DummyUIManager>>confirm: (in category 'ui requests') ----- >> confirm: queryString >> (ProvideAnswerNotification signal: queryString) >> ifNotNil: [:answer|^answer]. >> >> self error: 'No user response possible'! >> >> ----- Method: DummyUIManager>>confirm:orCancel: (in category 'ui >> requests') ----- >> confirm: aString orCancel: cancelBlock >> (ProvideAnswerNotification signal: aString) ifNotNil: [:answer | >> ^answer == #cancel ifTrue: [cancelBlock value] ifFalse: [answer]]. >> >> self error: 'No user response possible'! >> >> ----- Method: DummyUIManager>>displayProgress:at:from:to:during: (in >> category 'ui requests') ----- >> displayProgress: titleString at: aPoint from: minVal to: maxVal during: >> workBlock >> ^ workBlock value: Association new! >> >> ----- Method: DummyUIManager>>edit:label:accept: (in category 'ui >> requests') ----- >> edit: aText label: labelString accept: anAction >> ^ nil! >> >> ----- Method: DummyUIManager>>fontFromUser: (in category 'ui requests') >> ----- >> fontFromUser: priorFont >> self error: 'No user response possible'! >> >> ----- Method: DummyUIManager>>inform: (in category 'ui requests') ----- >> inform: aString >> "Nothing to be done here"! >> >> ----- Method: DummyUIManager>>informUserDuring: (in category 'ui >> requests') ----- >> informUserDuring: aBlock >> aBlock value: nil! >> >> ----- Method: DummyUIManager>>newDisplayDepthNoRestore: (in category >> 'display') ----- >> newDisplayDepthNoRestore: pixelSize >> "Change depths. Check if there is enough space!! , di" >> | area need | >> pixelSize = Display depth ifTrue: [^ self "no change"]. >> pixelSize abs < Display depth ifFalse: >> ["Make sure there is enough space" >> area := Display boundingBox area. "pixels" >> >> need := (area * (pixelSize abs - Display depth) // 8) >> "new bytes needed" >> + Smalltalk lowSpaceThreshold. >> (Smalltalk garbageCollectMost <= need >> and: [Smalltalk garbageCollect <= need]) >> ifTrue: [self error: 'Insufficient free space']]. >> Display setExtent: Display extent depth: pixelSize. >> >> DisplayScreen startUp! >> >> ----- Method: DummyUIManager>>request:initialAnswer: (in category 'ui >> requests') ----- >> request: queryString initialAnswer: defaultAnswer >> (ProvideAnswerNotification signal: queryString) >> ifNotNil: [:answer | >> ^ answer == #default ifTrue: [defaultAnswer] ifFalse: >> [answer]]. >> >> self error: 'No user response possible'! >> >> ----- Method: DummyUIManager>>requestPassword: (in category 'ui requests') >> ----- >> requestPassword: queryString >> ^ self request: queryString initialAnswer: ''! >> >> ----- Method: DummyUIManager>>restoreDisplay (in category 'display') ----- >> restoreDisplay! >> >> ----- Method: DummyUIManager>>restoreDisplayAfter: (in category 'display') >> ----- >> restoreDisplayAfter: aBlock >> aBlock value. >> Sensor waitButton.! >> >> StandardToolSet subclass: #CommandLineToolSet >> instanceVariableNames: '' >> classVariableNames: 'SaveSnapshotOnError' >> poolDictionaries: '' >> category: 'CommandLine-Tools'! >> >> ----- Method: CommandLineToolSet class>>debugError: (in category >> 'debugging') ----- >> debugError: anError >> "Print out a sensible stack trace and bail" >> | problemPlace s | >> self saveSnapshotOnError >> ifTrue: [Smalltalk saveAs: 'Debug-' , (Smalltalk imageName >> subStrings: '/') last]. >> problemPlace := anError signalerContext. >> s := FileStream stderr. >> (anError isKindOf: MessageNotUnderstood) ifTrue: [ >> s >> nextPutAll: anError messageText; cr; >> nextPutAll: problemPlace sender methodNode >> printString; cr]. >> (problemPlace stackOfSize: 20) do: [:ctx | s cr. ctx printOn: s]. >> s flush. >> >> SmalltalkImage current snapshot: false andQuit: true! >> >> ----- Method: CommandLineToolSet class>>debugSyntaxError: (in category >> 'debugging') ----- >> debugSyntaxError: anError >> | s | >> s := FileStream stderr. >> s nextPutAll: '----- Syntax error -----'; cr. >> s nextPutAll: anError errorCode; cr. >> s nextPutAll: '----- Syntax error -----'; cr. >> >> self debugError: anError! >> >> ----- Method: CommandLineToolSet class>>saveSnapshotOnError (in category >> 'preferences') ----- >> saveSnapshotOnError >> <preference: 'Save snapshot of image on failure' >> category: 'debug' >> description: 'If true, saves a snapshot of the failing image to >> the current directory.' >> type: #Boolean> >> ^ SaveSnapshotOnError ifNil: [SaveSnapshotOnError := false].! >> >> ----- Method: CommandLineToolSet class>>saveSnapshotOnError: (in category >> 'preferences') ----- >> saveSnapshotOnError: aBoolean >> SaveSnapshotOnError := aBoolean.! >> >> ----- Method: CommandLineToolSet class>>unload (in category 'class >> initialization') ----- >> unload >> ToolSet unregister: self.! >> >> > > > > |
In reply to this post by commits-2
Why did you use "SmalltalkImage current" instead of "Smalltalk?"
How about using the new Error>>#printDetailsOn:? Why does this need to be yet another new package instead of simply part of Tools? It's two classes that should never be unloaded, because command-line operations are something that should always be part of the system. On Thu, Oct 31, 2013 at 5:32 PM, <[hidden email]> wrote: > Frank Shearar uploaded a new version of CommandLine to project The Trunk: > http://source.squeak.org/trunk/CommandLine-fbs.1.mcz > > ==================== Summary ==================== > > Name: CommandLine-fbs.1 > Author: fbs > Time: 31 October 2013, 10:32:52.821 pm > UUID: dc871e85-bd16-d742-acbf-4d2b838113d1 > Ancestors: > > CommandLineToolSet does little more than dump errors to stderr. > > DummyUIManager comes from Pharo via Pavel Krivanek's minimising script. > > ==================== Snapshot ==================== > > SystemOrganization addCategory: #'CommandLine-Tools'! > SystemOrganization addCategory: #'CommandLine-UIManager'! > > UIManager subclass: #DummyUIManager > instanceVariableNames: '' > classVariableNames: '' > poolDictionaries: '' > category: 'CommandLine-UIManager'! > > !DummyUIManager commentStamp: 'fbs 10/31/2013 07:36' prior: 0! > I'm an alternative UIManager used to run an the image without GUI. I redefine methods which require user input as these requests are irrelevant in a headless environment. ! > > ----- Method: DummyUIManager>>checkForNewDisplaySize (in category 'display') ----- > checkForNewDisplaySize > Display extent = DisplayScreen actualScreenSize ifTrue: [^ self]. > DisplayScreen startUp. > ! > > ----- Method: DummyUIManager>>chooseDirectory:from: (in category 'ui requests') ----- > chooseDirectory: label from: dir > ^ nil! > > ----- Method: DummyUIManager>>chooseFrom:lines:title: (in category 'ui requests') ----- > chooseFrom: aList lines: linesArray title: aString > ^ aList first! > > ----- Method: DummyUIManager>>chooseFrom:values:lines:title: (in category 'ui requests') ----- > chooseFrom: labelList values: valueList lines: linesArray title: aString > ^ valueList first! > > ----- Method: DummyUIManager>>confirm: (in category 'ui requests') ----- > confirm: queryString > (ProvideAnswerNotification signal: queryString) > ifNotNil: [:answer|^answer]. > > self error: 'No user response possible'! > > ----- Method: DummyUIManager>>confirm:orCancel: (in category 'ui requests') ----- > confirm: aString orCancel: cancelBlock > (ProvideAnswerNotification signal: aString) ifNotNil: [:answer | > ^answer == #cancel ifTrue: [cancelBlock value] ifFalse: [answer]]. > > self error: 'No user response possible'! > > ----- Method: DummyUIManager>>displayProgress:at:from:to:during: (in category 'ui requests') ----- > displayProgress: titleString at: aPoint from: minVal to: maxVal during: workBlock > ^ workBlock value: Association new! > > ----- Method: DummyUIManager>>edit:label:accept: (in category 'ui requests') ----- > edit: aText label: labelString accept: anAction > ^ nil! > > ----- Method: DummyUIManager>>fontFromUser: (in category 'ui requests') ----- > fontFromUser: priorFont > self error: 'No user response possible'! > > ----- Method: DummyUIManager>>inform: (in category 'ui requests') ----- > inform: aString > "Nothing to be done here"! > > ----- Method: DummyUIManager>>informUserDuring: (in category 'ui requests') ----- > informUserDuring: aBlock > aBlock value: nil! > > ----- Method: DummyUIManager>>newDisplayDepthNoRestore: (in category 'display') ----- > newDisplayDepthNoRestore: pixelSize > "Change depths. Check if there is enough space!! , di" > | area need | > pixelSize = Display depth ifTrue: [^ self "no change"]. > pixelSize abs < Display depth ifFalse: > ["Make sure there is enough space" > area := Display boundingBox area. "pixels" > > need := (area * (pixelSize abs - Display depth) // 8) "new bytes needed" > + Smalltalk lowSpaceThreshold. > (Smalltalk garbageCollectMost <= need > and: [Smalltalk garbageCollect <= need]) > ifTrue: [self error: 'Insufficient free space']]. > Display setExtent: Display extent depth: pixelSize. > > DisplayScreen startUp! > > ----- Method: DummyUIManager>>request:initialAnswer: (in category 'ui requests') ----- > request: queryString initialAnswer: defaultAnswer > (ProvideAnswerNotification signal: queryString) > ifNotNil: [:answer | > ^ answer == #default ifTrue: [defaultAnswer] ifFalse: [answer]]. > > self error: 'No user response possible'! > > ----- Method: DummyUIManager>>requestPassword: (in category 'ui requests') ----- > requestPassword: queryString > ^ self request: queryString initialAnswer: ''! > > ----- Method: DummyUIManager>>restoreDisplay (in category 'display') ----- > restoreDisplay! > > ----- Method: DummyUIManager>>restoreDisplayAfter: (in category 'display') ----- > restoreDisplayAfter: aBlock > aBlock value. > Sensor waitButton.! > > StandardToolSet subclass: #CommandLineToolSet > instanceVariableNames: '' > classVariableNames: 'SaveSnapshotOnError' > poolDictionaries: '' > category: 'CommandLine-Tools'! > > ----- Method: CommandLineToolSet class>>debugError: (in category 'debugging') ----- > debugError: anError > "Print out a sensible stack trace and bail" > | problemPlace s | > self saveSnapshotOnError > ifTrue: [Smalltalk saveAs: 'Debug-' , (Smalltalk imageName subStrings: '/') last]. > problemPlace := anError signalerContext. > s := FileStream stderr. > (anError isKindOf: MessageNotUnderstood) ifTrue: [ > s > nextPutAll: anError messageText; cr; > nextPutAll: problemPlace sender methodNode printString; cr]. > (problemPlace stackOfSize: 20) do: [:ctx | s cr. ctx printOn: s]. > s flush. > > SmalltalkImage current snapshot: false andQuit: true! > > ----- Method: CommandLineToolSet class>>debugSyntaxError: (in category 'debugging') ----- > debugSyntaxError: anError > | s | > s := FileStream stderr. > s nextPutAll: '----- Syntax error -----'; cr. > s nextPutAll: anError errorCode; cr. > s nextPutAll: '----- Syntax error -----'; cr. > > self debugError: anError! > > ----- Method: CommandLineToolSet class>>saveSnapshotOnError (in category 'preferences') ----- > saveSnapshotOnError > <preference: 'Save snapshot of image on failure' > category: 'debug' > description: 'If true, saves a snapshot of the failing image to the current directory.' > type: #Boolean> > ^ SaveSnapshotOnError ifNil: [SaveSnapshotOnError := false].! > > ----- Method: CommandLineToolSet class>>saveSnapshotOnError: (in category 'preferences') ----- > saveSnapshotOnError: aBoolean > SaveSnapshotOnError := aBoolean.! > > ----- Method: CommandLineToolSet class>>unload (in category 'class initialization') ----- > unload > ToolSet unregister: self.! > > |
On 2 November 2013 20:37, Chris Muller <[hidden email]> wrote:
> Why did you use "SmalltalkImage current" instead of "Smalltalk?" Ignorance. I'll fix it. > How about using the new Error>>#printDetailsOn:? You mean Error >> #printVerboseOn: I presume? I could. One thing that CommandLineToolSet class >> #debugError: does that #printVerboseOn: doesn't, is that it prints out the source of the method in which an MNU occurs. It's there precisely because it's the only way to figure out what the heck just happened in the event of an MNU. > Why does this need to be yet another new package instead of simply > part of Tools? It's two classes that should never be unloaded, > because command-line operations are something that should always be > part of the system. It should be a separate package because it serves a different purpose. CommandLineToolSet provides some basic infrastructure for command line things. StandardToolSet does the same for a headful image. The two should not belong in the same package any more than MorphicUIManager and ST80UIManager do. You're nearly right in that they should never be unloaded. (Because a truly minimal image would be able to do nothing but load another package.) But Tools should be :) frank > On Thu, Oct 31, 2013 at 5:32 PM, <[hidden email]> wrote: >> Frank Shearar uploaded a new version of CommandLine to project The Trunk: >> http://source.squeak.org/trunk/CommandLine-fbs.1.mcz >> >> ==================== Summary ==================== >> >> Name: CommandLine-fbs.1 >> Author: fbs >> Time: 31 October 2013, 10:32:52.821 pm >> UUID: dc871e85-bd16-d742-acbf-4d2b838113d1 >> Ancestors: >> >> CommandLineToolSet does little more than dump errors to stderr. >> >> DummyUIManager comes from Pharo via Pavel Krivanek's minimising script. >> >> ==================== Snapshot ==================== >> >> SystemOrganization addCategory: #'CommandLine-Tools'! >> SystemOrganization addCategory: #'CommandLine-UIManager'! >> >> UIManager subclass: #DummyUIManager >> instanceVariableNames: '' >> classVariableNames: '' >> poolDictionaries: '' >> category: 'CommandLine-UIManager'! >> >> !DummyUIManager commentStamp: 'fbs 10/31/2013 07:36' prior: 0! >> I'm an alternative UIManager used to run an the image without GUI. I redefine methods which require user input as these requests are irrelevant in a headless environment. ! >> >> ----- Method: DummyUIManager>>checkForNewDisplaySize (in category 'display') ----- >> checkForNewDisplaySize >> Display extent = DisplayScreen actualScreenSize ifTrue: [^ self]. >> DisplayScreen startUp. >> ! >> >> ----- Method: DummyUIManager>>chooseDirectory:from: (in category 'ui requests') ----- >> chooseDirectory: label from: dir >> ^ nil! >> >> ----- Method: DummyUIManager>>chooseFrom:lines:title: (in category 'ui requests') ----- >> chooseFrom: aList lines: linesArray title: aString >> ^ aList first! >> >> ----- Method: DummyUIManager>>chooseFrom:values:lines:title: (in category 'ui requests') ----- >> chooseFrom: labelList values: valueList lines: linesArray title: aString >> ^ valueList first! >> >> ----- Method: DummyUIManager>>confirm: (in category 'ui requests') ----- >> confirm: queryString >> (ProvideAnswerNotification signal: queryString) >> ifNotNil: [:answer|^answer]. >> >> self error: 'No user response possible'! >> >> ----- Method: DummyUIManager>>confirm:orCancel: (in category 'ui requests') ----- >> confirm: aString orCancel: cancelBlock >> (ProvideAnswerNotification signal: aString) ifNotNil: [:answer | >> ^answer == #cancel ifTrue: [cancelBlock value] ifFalse: [answer]]. >> >> self error: 'No user response possible'! >> >> ----- Method: DummyUIManager>>displayProgress:at:from:to:during: (in category 'ui requests') ----- >> displayProgress: titleString at: aPoint from: minVal to: maxVal during: workBlock >> ^ workBlock value: Association new! >> >> ----- Method: DummyUIManager>>edit:label:accept: (in category 'ui requests') ----- >> edit: aText label: labelString accept: anAction >> ^ nil! >> >> ----- Method: DummyUIManager>>fontFromUser: (in category 'ui requests') ----- >> fontFromUser: priorFont >> self error: 'No user response possible'! >> >> ----- Method: DummyUIManager>>inform: (in category 'ui requests') ----- >> inform: aString >> "Nothing to be done here"! >> >> ----- Method: DummyUIManager>>informUserDuring: (in category 'ui requests') ----- >> informUserDuring: aBlock >> aBlock value: nil! >> >> ----- Method: DummyUIManager>>newDisplayDepthNoRestore: (in category 'display') ----- >> newDisplayDepthNoRestore: pixelSize >> "Change depths. Check if there is enough space!! , di" >> | area need | >> pixelSize = Display depth ifTrue: [^ self "no change"]. >> pixelSize abs < Display depth ifFalse: >> ["Make sure there is enough space" >> area := Display boundingBox area. "pixels" >> >> need := (area * (pixelSize abs - Display depth) // 8) "new bytes needed" >> + Smalltalk lowSpaceThreshold. >> (Smalltalk garbageCollectMost <= need >> and: [Smalltalk garbageCollect <= need]) >> ifTrue: [self error: 'Insufficient free space']]. >> Display setExtent: Display extent depth: pixelSize. >> >> DisplayScreen startUp! >> >> ----- Method: DummyUIManager>>request:initialAnswer: (in category 'ui requests') ----- >> request: queryString initialAnswer: defaultAnswer >> (ProvideAnswerNotification signal: queryString) >> ifNotNil: [:answer | >> ^ answer == #default ifTrue: [defaultAnswer] ifFalse: [answer]]. >> >> self error: 'No user response possible'! >> >> ----- Method: DummyUIManager>>requestPassword: (in category 'ui requests') ----- >> requestPassword: queryString >> ^ self request: queryString initialAnswer: ''! >> >> ----- Method: DummyUIManager>>restoreDisplay (in category 'display') ----- >> restoreDisplay! >> >> ----- Method: DummyUIManager>>restoreDisplayAfter: (in category 'display') ----- >> restoreDisplayAfter: aBlock >> aBlock value. >> Sensor waitButton.! >> >> StandardToolSet subclass: #CommandLineToolSet >> instanceVariableNames: '' >> classVariableNames: 'SaveSnapshotOnError' >> poolDictionaries: '' >> category: 'CommandLine-Tools'! >> >> ----- Method: CommandLineToolSet class>>debugError: (in category 'debugging') ----- >> debugError: anError >> "Print out a sensible stack trace and bail" >> | problemPlace s | >> self saveSnapshotOnError >> ifTrue: [Smalltalk saveAs: 'Debug-' , (Smalltalk imageName subStrings: '/') last]. >> problemPlace := anError signalerContext. >> s := FileStream stderr. >> (anError isKindOf: MessageNotUnderstood) ifTrue: [ >> s >> nextPutAll: anError messageText; cr; >> nextPutAll: problemPlace sender methodNode printString; cr]. >> (problemPlace stackOfSize: 20) do: [:ctx | s cr. ctx printOn: s]. >> s flush. >> >> SmalltalkImage current snapshot: false andQuit: true! >> >> ----- Method: CommandLineToolSet class>>debugSyntaxError: (in category 'debugging') ----- >> debugSyntaxError: anError >> | s | >> s := FileStream stderr. >> s nextPutAll: '----- Syntax error -----'; cr. >> s nextPutAll: anError errorCode; cr. >> s nextPutAll: '----- Syntax error -----'; cr. >> >> self debugError: anError! >> >> ----- Method: CommandLineToolSet class>>saveSnapshotOnError (in category 'preferences') ----- >> saveSnapshotOnError >> <preference: 'Save snapshot of image on failure' >> category: 'debug' >> description: 'If true, saves a snapshot of the failing image to the current directory.' >> type: #Boolean> >> ^ SaveSnapshotOnError ifNil: [SaveSnapshotOnError := false].! >> >> ----- Method: CommandLineToolSet class>>saveSnapshotOnError: (in category 'preferences') ----- >> saveSnapshotOnError: aBoolean >> SaveSnapshotOnError := aBoolean.! >> >> ----- Method: CommandLineToolSet class>>unload (in category 'class initialization') ----- >> unload >> ToolSet unregister: self.! >> >> > |
>> How about using the new Error>>#printDetailsOn:?
> > You mean Error >> #printVerboseOn: I presume? I could. One thing that > CommandLineToolSet class >> #debugError: does that #printVerboseOn: > doesn't, is that it prints out the source of the method in which an > MNU occurs. It's there precisely because it's the only way to figure > out what the heck just happened in the event of an MNU. It seems like the purposes of the two methods are the same -- to print a lot of information about the error to a stream so it can be somewhat understood and somewhat debugged outside of the image environment. I'm not opposed if you can enhance it to include the source of the offending method. >> Why does this need to be yet another new package instead of simply >> part of Tools? It's two classes that should never be unloaded, >> because command-line operations are something that should always be >> part of the system. > > It should be a separate package because it serves a different purpose. Is that a good reason? > CommandLineToolSet provides some basic infrastructure for command line > things. StandardToolSet does the same for a headful image. The two > should not belong in the same package any more than MorphicUIManager > and ST80UIManager do. Morphic and ST80 are entire graphical frameworks, but CommandLineTools is for supporting a headless system on a core "engine". If you're still saying it should be a separate package, maybe you're making a case that it should be an external package? Modules don't scale in all the dimensions we need them to scale anyway, so shouldn't we take a reasonably pragmatic (vs. purist) approach to defining package boundaries? "Truly minimal" will never be achieved even if we defined hundreds of tiny little packages, because there'll always be some extra classes and/or methods which "serve a different purpose" than what is truly minimally required for application XYZ. And yet, moving toward micro-modules increases the complexity for humankind to assemble working systems. If we really care about truly minimal I think we should get Spoon going and leave the packages reasonably chunky-grained.. There'll always be the need for various "shrinking" acitivities if someone is concerned about that, and such shrinkage can include unloading individual classes if they wish. > You're nearly right in that they should never be unloaded. (Because a > truly minimal image would be able to do nothing but load another > package.) But Tools should be :) |
On 2 November 2013 23:42, Chris Muller <[hidden email]> wrote:
>>> How about using the new Error>>#printDetailsOn:? >> >> You mean Error >> #printVerboseOn: I presume? I could. One thing that >> CommandLineToolSet class >> #debugError: does that #printVerboseOn: >> doesn't, is that it prints out the source of the method in which an >> MNU occurs. It's there precisely because it's the only way to figure >> out what the heck just happened in the event of an MNU. > > It seems like the purposes of the two methods are the same -- to print > a lot of information about the error to a stream so it can be somewhat > understood and somewhat debugged outside of the image environment. > I'm not opposed if you can enhance it to include the source of the > offending method. If you're suggesting that I move the CommandLineToolSet's extra info displaying into Error, and then using Error's new abilities, sure, I'm OK with that. That scratches both our itches. >>> Why does this need to be yet another new package instead of simply >>> part of Tools? It's two classes that should never be unloaded, >>> because command-line operations are something that should always be >>> part of the system. >> >> It should be a separate package because it serves a different purpose. > > Is that a good reason? Yes :) Take the opposite extreme: we can trivially solve all this complexity about packages by having a single, gigantic package called Squeak. Job done. >> CommandLineToolSet provides some basic infrastructure for command line >> things. StandardToolSet does the same for a headful image. The two >> should not belong in the same package any more than MorphicUIManager >> and ST80UIManager do. > > Morphic and ST80 are entire graphical frameworks, but CommandLineTools > is for supporting a headless system on a core "engine". If you're > still saying it should be a separate package, maybe you're making a > case that it should be an external package? It should be an external package, but then so should Morphic. But since we're nowhere near moving Morphic to an external package, and since CI is rather important, the pragmatic approach would be to leave it in Trunk. Or, if you prefer, I think it's more important to have CommandLineToolSet in Trunk than it is to have Tools/Morphic in Trunk. > Modules don't scale in all the dimensions we need them to scale > anyway, so shouldn't we take a reasonably pragmatic (vs. purist) > approach to defining package boundaries? "Truly minimal" will never > be achieved even if we defined hundreds of tiny little packages, > because there'll always be some extra classes and/or methods which > "serve a different purpose" than what is truly minimally required for > application XYZ. > > And yet, moving toward micro-modules increases the complexity for > humankind to assemble working systems. If we really care about truly > minimal I think we should get Spoon going and leave the packages > reasonably chunky-grained.. There'll always be the need for various > "shrinking" acitivities if someone is concerned about that, and such > shrinkage can include unloading individual classes if they wish. No, that's just the thing. Moving towards smaller packages makes it _easier_ to assemble these things, because you don't build your system out of giant baroque shapes, but simple little pieces. There is a middle ground between our gigantic all-the-things packages and "micro-modules" (I'm not sure how small things need to be before they're micro, nor why small is bad. My Maybe and Either packages are both a single class, and that's exactly the size package they ought to be.) I care a lot about minimalism, but I am _not_ tackling minimalism. I am attacking _modularity_, which is related but not identical. I do not want to shrink or melt things. I want to build things out of separate parts. I want Lego, not lost wax castings. Look at System, for instance. It has high level parts, and low level parts. It depends on just about everything in the image: Collections, Compiler, Compression, Environments, Files, Graphics, 'Installer-Core', Kernel, Monticello, MonticelloConfigurations, Morphic, MorphicExtras, Multilingual, Network, 'PackageInfo-Base', Sound, 'ToolBuilder-Kernel', Tools, TrueType. And yet it's supposedly "low level". PARTS of System are low level, and PARTS of System are high level, and these parts do not belong in the same package. The only solution to that (that is not simply giving up) is to add more packages. And you know what? That's OK. We're not talking about 1000 packages, we're talking about maybe a few more dozen. I'm sure our tools can handle that. And if they can't, we should make better tools. frank |
Free forum by Nabble | Edit this page |