'From Pharo-1.1.1-- of 12 September 2010 [Latest update: #11414] on 7 February 2012 at 10:43:13 am'! Object subclass: #Migrate instanceVariableNames: 'packageCache homeGrownPackages localOnly log' classVariableNames: '' poolDictionaries: '' category: 'Migrate-Core'! !Migrate commentStamp: '' prior: 0! Another gratuitous loader. CONFIGURE ========= Configure it using #homeGrownPackageNames and #me to tell it which packages are intended to hold your work, and how to identify you from the (misnomer!!!!!!) #timeStamp aspects of the compiled methods you produce. SAVE YOUR WORK ============== Use #suspectMethodsReport to produce a listing of class>>selector names that might be in danger of being orphaned in your current image. Use #homeGrownPackgesSaveWithMessage: to save all of the identified home grown packages in the next version and with the common text message. BUILD A NEW IMAGE ================= Load Migrate into a new image. If you want a web image, evaluate #web and then save the image. It wants underscore_madness.cs, and loads SIXX and other packages of interest to me; you can edit as needed to remove what you do not want to load. Put your packages in the cache directory for the new image. Yes, it is fussy about these things, but the idea is to find errors early rather than being stopped after a long wait. Likewise, if you do not like what #setPreferences does, edit it. TO SHARE CODE NON-MC ==================== To share code, try: curl -T GiveThisToStef.mcz http://www.squeaksource.com/PharoInbox W.K. Schwab, Ph.D. This is released under standard Pharo licensing with no warranty of any kind. ! ]style[(1147 92 101)f1,f2,f1! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 2/5/2012 12:02'! basicLoadPackages "1-12 - lots of change. Use #web and then loadPackages.." | wks | wks := packageCache. "1-12 - better left to manual install? Most of my Dolphin code is here now. self loadLatestPackage:'SIF-Support' fromRepository:wks; loadLatestPackage:'SIF-Squeak' fromRepository:wks." "11-09 - factor out the names that should contain methods that are *not* in danger of being lost for want of packaging. 10-10 - trying to load Migrate, which belongs in the list for suspect methods search and not here.." self homeGrownPackages allButFirst do:[ :each | self log:each packageName. self loadLatestPackage:each packageName fromRepository:wks. ] displayingProgress:'Loading Home-grown Packages'. ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 4/15/2010 17:05'! checkHomeGrownPackagesForLoad "11-09 - look for existing versions of all named packages - in short, don't blow up over stupid stuff _after_ installing a bunch of code." self homeGrownPackages. self homeGrownPackages allButFirstDo:[ :each | self assert:[ ( self versionsAvailableForPackage:( PackageInfo named:each packageName ) in:packageCache ) notEmpty ]. ]. " Migrate default checkHomeGrownPackagesForLoad. Migrate default checkHomeGrownPackagesForSave. " ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 11/3/2009 20:11'! checkHomeGrownPackagesForSave "11-09 - a breif sanity check on the packages; at least see if they contain some methods. A method-less class won't like this, but I'm losing way too much time to avoidable non-sense for want of a real package system; this should slow the bleeding." self homeGrownPackages. self homeGrownPackages do:[ :each | self assert:[ each methods notEmpty ]. ]. " Migrate new checkHomeGrownPackagesForLoad. Migrate new checkHomeGrownPackagesForSave. " ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 1/12/2010 19:15'! homeGrownPackageFor:method ifNone:ifNone "11-09 - starting to understand why OB is so slow; there appears to be no direct path from method to package." | selector aClass | selector := method selector. aClass := method methodClass. "11-09 - try to luck out and early out method methodClass methods includes:method." ^homeGrownPackages detect:[ :aPackage | aPackage includesMethod:selector ofClass:aClass. "method category. method methodClass." ] ifNone:ifNone. ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 10/3/2010 22:17'! homeGrownPackages "11-09 - answer a collection of packages allegedly representing the work of the programmer identified by #me. Add the Migrate package as the first in the collection; it is skipped using #allButFirstDo: in various places." | aClass | homeGrownPackages notNil ifTrue:[ ^homeGrownPackages. ]. homeGrownPackages := ( self homeGrownPackageNames collect:[ :each | "11-09 - can't do this here; sometimes we care about whole packages in the images, and sometimes about extant versions in the cache. See #checkHomeGrownPackagesFor*. self assert:[ PackageInfo existPackageNamed:each. ]." PackageInfo named:each. ] ) asOrderedCollection. "11-09 - lots of bogus complaints over Migrate members, so add it to the collection of packages. This allows the search for endangered work to include migrate and all subclass' packages, while leaving them out of #homeGrownPackageNames which is used to load the packages into the new image. Migrate and friends are loaded separately, so should not be loaded again. 1-10 - with Migrate-Core, etc., just add Migrate's package. aClass := self class. [ aClass notNil ] whileTrue:[ homeGrownPackages addFirst:aClass package. aClass := aClass = Migrate ifTrue:[ nil. ] ifFalse:[ aClass superclass. ]. ]. homeGrownPackages addFirst:Migrate package." "9-10 - this is being a pain again - try adding the receiver (presumably not a Migrate) to the collection. 10-10 - this is being a major pain. Give it one more chance. homeGrownPackages addFirst:self class package; addFirst:Migrate package." homeGrownPackages first = self class package ifFalse:[ homeGrownPackages addFirst:self class package. ]. ^homeGrownPackages. " Migrate default homeGrownPackages. " ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 1/12/2010 19:12'! initialize super initialize. packageCache := MCCacheRepository default. self homeGrownPackages. localOnly := false. log := LogFile fileName:'migrate.log'. " Migrate default suspectMethodsReport. Migrate default homeGrownPackagesSaveWithMessage:'Automated save'. Do this and then save the image!! Migrate default web. Migrate default loadPackages. Migrate default loadPackagesLocalOnly. " ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 11/2/2009 23:12'! isHomeGrown:method ^( method timeStamp indexOfSubCollection:self me ) ~= 0 ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 11/11/2009 14:14'! log:aString log log:aString. ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 11/9/2009 17:23'! preLoad "10-09 - hooks for things to do before loadling packages." ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 2/6/2012 04:41'! saveImage "1-12 - losing way too much time.... But this is NOT the answer..." " SmalltalkImage current saveSession." ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 1/12/2010 19:16'! savePackageNamed:packageName message:aString "11-09 - Saving packages one-off using MC is error prone, not to mention just plain pointless. Save the next version of each of the home grown packages using a common message." | wc version | wc := ( MCPackage named:packageName ) workingCopy. version := wc newVersionWithName:wc uniqueVersionName message:aString. packageCache storeVersion:version. " Migrate default homeGrownPackagesSaveWithMessage:'Automate this'. " ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 2/6/2012 04:15'! setPreferences "Set toolset, fonts, theme; turn off ecompletion." | tinyFont codeFont baseFont boldFont | "10-10 - the new inspector is back - nuke it. ToolSet default:StandardToolSet. SystemBrowser default:Browser. 1-12 - returning to this after a long gap; set just the theme for now?" UIThemeW2K beCurrent. "1-12 - font incantation" FreeTypeFontProvider current families isEmpty ifTrue:[ FreeTypeFontProvider current updateFromSystem. ]. Author fullName:self meFull. "Select Fonts - Shamelessly stolen from Lukas. 1-12 - tryin to get this back w/ new settings system" tinyFont := LogicalFont familyName:'DejaVu Sans' fallbackFamilyNames:nil pointSize:8 stretchValue:0 weightValue:400 slantValue:0. codeFont := LogicalFont familyName:'DejaVu Sans Mono' fallbackFamilyNames:nil pointSize:12 stretchValue:0 weightValue:400 slantValue:0. baseFont := LogicalFont familyName:'DejaVu Sans' fallbackFamilyNames:nil pointSize:12 stretchValue:0 weightValue:400 slantValue:0. boldFont := LogicalFont familyName:'DejaVu Sans' fallbackFamilyNames:nil pointSize:11 stretchValue:0 weightValue:600 slantValue:0. StandardFonts listFont: baseFont; menuFont: baseFont; codeFont: codeFont; buttonFont: baseFont; defaultFont: baseFont; windowTitleFont: boldFont. " Migrate default setPreferences. " ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 1/12/2010 19:16'! suspectMethods "11-09 - answer a collection of methods authored (per #timeStamp - misnamed!!!!) by 'me' and not in one of the #homeGrownPackages. Look for them now, or look for them later." | out | out := Array writeStream. self homeGrownPackages. ProtoObject allSubclasses do:[ :aClass | aClass methods do:[ :method | ( self isHomeGrown:method ) ifTrue:[ "11-09 - written here. Is it packaged in kind?" self homeGrownPackageFor:method ifNone:[ out nextPut:method. ]. ]. ]. ] displayingProgress:'Looking for unpackaged code'. ^out contents. " Migrate default suspectMethods. " ! ! !Migrate methodsFor: 'helpers' stamp: 'BillSchwab 4/15/2010 17:05'! versionsAvailableForPackage: aPackage in:repository "4-10 - stolen/adapted from O2." ^repository allVersionNames select: [:versionName | versionName beginsWith: aPackage packageName] ! ! !Migrate methodsFor: 'configuration' stamp: 'BillSchwab 11/11/2009 11:30'! homeGrownPackageNames "Override to answer a collection of package names to be overseen by Migrate. These are the 'home-grown' packages used in #suspectMethods (looking for work that would be lost for want of packaging), saved by #homeGrownPackagesSaveWihMessage:, and loaded into a new image as part of #loadPackages." ^OrderedCollection new. ! ! !Migrate methodsFor: 'configuration' stamp: 'BillSchwab 11/7/2009 14:09'! me "Answer a string to be found in the (yuk!!!!) #timeStamp of methods that represent work to be saved in packages." self shouldBeImplemented. ! ! !Migrate methodsFor: 'configuration' stamp: 'BillSchwab 2/6/2012 04:09'! meFull "Answer a string for the author full name." self shouldBeImplemented. ! ! !Migrate methodsFor: 'save packages' stamp: 'BillSchwab 2/1/2012 04:45'! homeGrownPackagesSaveWithMessage:aString "11-09 - Save the 'next version' of each of the home-grown packages." "11-09 - undone work is the most common cause of hassle here, so do some type of check on the integrity of the packages. Is having methods enough?" self checkHomeGrownPackagesForSave. self homeGrownPackages allButFirst do:[ :each | self savePackageNamed:each packageName message:aString. ] displayingProgress:'Saving Home-grown Packages'. " Migrate default saveMigrate. Migrate default homeGrownPackagesSaveWithMessage:''Save for new image'.. " ! ! !Migrate methodsFor: 'save packages' stamp: 'BillSchwab 2/5/2012 11:57'! saveMigrate "11-09 - typical usage will likely be to subclass Migrate, so saving it and all sub-class' packages will be helpful. 1-10 - changing to Migrate-Core, etc., so it should suffice to save only Migrate's package." "1-10 Migrate withAllSubclasses do:[ :aClass | self savePackageNamed:aClass package packageName message:'Migrate'. ]." self savePackageNamed:Migrate package packageName message:'Migrate'. " Migrate default saveMigrate. " ! ! !Migrate methodsFor: 'build image basics' stamp: 'BillSchwab 2/7/2012 10:38'! loadCitezen "1-10 - load Citezen if not installed. 4-10 - this appears to load Seaside too. 6-10 - will no longer load Seaside." Smalltalk at:#CZAuthor ifPresent:[ :aClass | ^self. ]. "2-12 - from Stef (ConfigurationOfCitezen project version: #stable) load: { 'NoWeb'}." self loadMetacelloConfiguration:'Citezen' version:#stable load:{ 'NoWeb'}. " Migrate default loadCitezen. Migrate default loadOSProcess. Migrate default loadSeaside. " ! ! !Migrate methodsFor: 'build image basics' stamp: 'BillSchwab 2/5/2012 10:59'! loadFFI "1-10 - load FFI if not installed.. 1-12 add Alien for callbacks." Smalltalk at:#ExternalStructure ifPresent:[ :aClass | ^self. ]. "7-11 - self loadMetacelloPackage:'FFI' version:'1.2'." self loadMetacelloPackage:'FFI' version:nil. self loadMetacelloPackage:'Alien' version:nil. "1-12 - enough wasted time...." self saveImage. " Migrate default loadFFI. " ! ! !Migrate methodsFor: 'build image basics' stamp: 'BillSchwab 2/5/2012 11:56'! loadLDAP "1-12 - load ldap - no configOf??" self loadLatestPackage:'LDAP' fromSqueaksource:'LDAPlayer'. self saveImage. ! ! !Migrate methodsFor: 'build image basics' stamp: 'BillSchwab 2/5/2012 11:51'! loadODBC "metacello configuration available." "3-11 - previously, this was done as: SARInstaller installSAR:'package-cache/SIXX20091115.sar'. " Gofer new squeaksource:'MetacelloRepository'; package:'ConfigurationOfODBC'; load. (Smalltalk at:#ConfigurationOfODBC) load. self saveImage.! ! !Migrate methodsFor: 'build image basics' stamp: 'BillSchwab 2/7/2012 10:36'! loadOSProcess "1-10 - load OS Process if not installed." Smalltalk at:#OSProcess ifPresent:[ :aClass | ^self. ]. self loadMetacelloPackage:'OSProcess' version:nil. "1-12 - enough wasted time...." self saveImage. " Migrate default loadOSProcess. " ! ! !Migrate methodsFor: 'build image basics' stamp: 'BillSchwab 2/5/2012 10:57'! loadOSProcessCommandShell "1-10 - load OS Process if not installed." "4-10 - this is getting old. Smalltalk at:#ConfigurationOfOSProcess ifPresent:[ :aClass | ^self. ]." self loadLatestPackage:'CommandShell' fromSqueaksource:'CommandShell'. "1-12 - enough wasted time...." self saveImage. " Migrate default loadOSProcessCommandShell. " ! ! !Migrate methodsFor: 'build image basics' stamp: 'BillSchwab 2/5/2012 11:52'! loadSIXX "3-11 - metacello configuration available." "3-11 - previously, this was done as: SARInstaller installSAR:'package-cache/SIXX20091115.sar'. " Gofer new squeaksource:'MetacelloRepository'; package:'ConfigurationOfSIXX'; load. (Smalltalk at:#ConfigurationOfSIXX) load. self saveImage. ! ! !Migrate methodsFor: 'build image basics' stamp: 'BillSchwab 2/6/2012 12:45'! loadSeaside "2-12 - current version of how to do this?? Load 3.0 and Magritte2." Smalltalk at:#WAComponent ifPresent:[ :aClass | ^self. ]. (Smalltalk at: #Gofer) new squeaksource: 'MetacelloRepository'; package: 'ConfigurationOfSeaside'; load. (Smalltalk at:#ConfigurationOfSeaside) project latestVersion load: #( 'Seaside 3.0' 'Magritte2' ). ! ! !Migrate methodsFor: 'build image' stamp: 'BillSchwab 2/5/2012 11:38'! loadPackages "10-09 - build an image. I have no idea what's up with installer/gofer, etc., and now can't reliably copy text between images. MC seems to work, so create class to do all of this." self checkHomeGrownPackagesForLoad. "self setPreferences." self preLoad. self basicLoadPackages. ( Smalltalk at:#ExternalStructure ) allSubclassesDo: [:each | each compileFields]. " Do this and then save the image!! Migrate default web. Migrate default loadPackages. Migrate default loadPackagesLocalOnly. " ! ! !Migrate methodsFor: 'build image' stamp: 'BillSchwab 9/16/2011 05:13'! loadPackagesLocalOnly "10-09 - build an image. I have no idea what's up with installer/gofer, etc., and now can't reliably copy text between images. MC seems to work, so create class to do all of this." self useOnlyLocalRepositories. self loadPackages. " Do this and then save the image!! Migrate default web. Migrate default loadPackages. Migrate default loadPackagesLocalOnly. " ! ! !Migrate methodsFor: 'build image' stamp: 'BillSchwab 9/16/2011 05:13'! useOnlyLocalRepositories "11-09 - squeak foundation down; not the first time, won't be the last." localOnly := true. " Do this and then save the image!! Migrate default web. Migrate default loadPackages. Migrate default loadPackagesLocalOnly. " ! ! !Migrate methodsFor: 'check for endangered work' stamp: 'BillSchwab 9/16/2011 05:10'! suspectMethodsReport | methods out ws | methods := self suspectMethods. out := String writeStream. out nextPutAll:'Below is a list of methods attributable to '; nextPutAll:self me; nextPutAll:' but not packaged in one of the #homeGrownPackageNames.'; cr; nextPutAll:'They might be at risk of being orphaned as you build a new image.'; cr; cr. methods do:[ :each | out nextPutAll:each methodClass name; nextPutAll:'>>'; nextPutAll:each selector. ] separatedBy:[ out cr. ]. ws := Workspace new contents:out contents. ws openLabel:'Suspect Methods'. ! ! !Migrate methodsFor: 'deprecated' stamp: 'BillSchwab 2/6/2012 07:26'! loadMetacelloPackage:name version:versionStringOrNil "1-10 - way too much sugar. 2-12 - I am reaching the point of declaring Metacello a failure. The situation is improving, but it is still unusable IMHO." | aGofer fullName config project tryThese | fullName := name. ( fullName beginsWith:'ConfigurationOf' ) ifFalse:[ fullName := 'ConfigurationOf', fullName. ]. "1-10 - now multiple messages to the same configuration (which makes sense)" Smalltalk at:fullName asSymbol ifAbsent:[ Gofer new squeaksource:'MetacelloRepository'; package:fullName; load. ]. config := Smalltalk at:fullName asSymbol. project := config project. "7-11 - configs load differently every time - try to make one thing that can work." tryThese := { [config load. ]. [ project stableVersion load. ]. [ project latestVersion load. ]. }. versionStringOrNil isNil ifTrue:[ "7-11 - can this mask complexities? Consider also #canUnderstand: config load." tryThese detect:[ :each | [ each value. true. ] on:Error do:[ :e | false. ]. ]. ] ifFalse:[ ( config project version:versionStringOrNil ) load. ]. ! ! !Migrate methodsFor: 'deprecated' stamp: 'BillSchwab 1/16/2010 18:32'! loadVMMaker self loadAlien. self loadFFI. "self loadMetacelloPackage:'PharoSound' version:'1.0'." Gofer new squeaksource:'VMMaker'; package: 'VMMaker'; load. ! ! !Migrate methodsFor: 'deprecated' stamp: 'BillSchwab 2/6/2012 12:25'! web "1-10 - no more web images. Get rid of the specifics when Loader is released. Do this first and SAVE THE IMAGE to avoid wasting time. As of 2-12, having so much trouble w/ configOf* that this is useless going into 1.3." "4-10 - try this differently. self loadSeaside; loadFFI; loadAlien; loadVMMaker. 6-10 - Citezen now separate, so load Seaside." self setPreferences; loadFFI; loadSIXX; loadODBC; loadLDAP; loadOSProcess; loadOSProcessCommandShell; loadCitezen; loadSeaside; loadMagritte. "1-12 - enough wasted time...." self saveImage. " Migrate default suspectMethodsReport. Migrate default saveMigrate. Migrate default homeGrownPackagesSaveWithMessage:'For building 1.3'. Do this and then save the image!! Migrate default setPreferences. Migrate default web. Migrate default loadPackages. Migrate default loadPackagesLocalOnly. " ! ! !Migrate methodsFor: 'helpers-metacello' stamp: 'BillSchwab 2/7/2012 10:32'! loadMetacelloConfiguration:name "2-12 - WAY too much syntactic sugar; a common base class for configurations would not hurt (say it once). We need to know the project name, version, if any, and what elements to load." self loadMetacelloConfiguration:name version:nil load:#(). ! ! !Migrate methodsFor: 'helpers-metacello' stamp: 'BillSchwab 2/7/2012 10:31'! loadMetacelloConfiguration:name version:versionSymbol "2-12 - WAY too much syntactic sugar; a common base class for configurations would not hurt (say it once). We need to know the project name, version, if any, and what elements to load." self loadMetacelloConfiguration:name version:versionSymbol load:#(). ! ! !Migrate methodsFor: 'helpers-metacello' stamp: 'BillSchwab 2/7/2012 10:25'! loadMetacelloConfiguration:name version:versionSymbol load:strings "2-12 - WAY too much syntactic sugar; a common base class for configurations would not hurt (say it once). We need to know the project name, version, if any, and what elements to load. (ConfigurationOfCitezen project version: #stable) load: { 'NoWeb'}. Gofer new squeaksource: 'Fuel'; package: 'ConfigurationOfFuel'; load. (Smalltalk at: #ConfigurationOfFuel) load. " | config receiver | "2-12 - I type fast, but really..." config := ( 'ConfigurationOf', name ) asSymbol. "2-12 - get the configuration" Gofer new squeaksource:name; package:config asString; load. "2-12 - how shall I load thee, let me count the ways... Start by getting the receiver to use." receiver := versionSymbol notNil ifTrue:[ config project version:versionSymbol. ] ifFalse:[ config. ]. "2-12 - load specific items or just #load?" strings notEmpty ifTrue:[ receiver load:strings. ] ifFalse:[ receiver load. ]. ! ! !Migrate methodsFor: 'helpers-load-latest' stamp: 'BillSchwab 1/16/2010 18:22'! loadLatestPackage: aString from: url | repository | repository := MCHttpRepository location:url user: '' password: ''. self loadLatestPackage: aString fromRepository: repository. ! ! !Migrate methodsFor: 'helpers-load-latest' stamp: 'BillSchwab 1/16/2010 18:20'! loadLatestPackage: aString fromRepository: aRepository "1-10 - too useful to be without really, I created another. Shamelessly stolen from ScriptLoader." | versionsBlock versions tries version | versionsBlock := [ (aRepository allVersionNames select: [ :each | each beginsWith: aString ]) asSortedCollection: [ :a :b | (a copyAfterLast: $.) asNumber <= (b copyAfterLast: $.) asNumber]]. versions := versionsBlock value. tries := 0. [ versions isEmpty and: [ tries < 3 ] ] whileTrue: [ versions := versionsBlock value. tries := tries + 1 ]. versions isEmpty ifTrue: [ self error: 'problems when accessing repository' ]. aRepository versionReaderForFileNamed: (versions last , '.mcz') do: [:reader | version := reader version. version load. version workingCopy repositoryGroup addRepository: aRepository]. ! ! !Migrate methodsFor: 'helpers-load-latest' stamp: 'BillSchwab 1/16/2010 18:23'! loadLatestPackage: aString fromSqueaksource: aDirectoryName " self loadLatestPackage: 'ScriptLoader' fromSqueaksource: 'Pharo' " self loadLatestPackage: aString from: 'http://www.squeaksource.com/', aDirectoryName ! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! Migrate class instanceVariableNames: ''! !Migrate class methodsFor: 'as yet unclassified' stamp: 'BillSchwab 2/6/2012 04:33'! default "1-10 - cheat to allow subclasses to be automatically detected and used; there can be only one, subclass that is, but that should suffice." | classes | classes := Migrate allSubclasses asOrderedCollection. self assert:[ classes size = 1. ]. ^classes first new. ! ! !Migrate class methodsFor: 'as yet unclassified' stamp: 'BillSchwab 8/31/2010 17:05'! packageNamesStartingWith:aString ^( PackageOrganizer default packageNames select:[ :each | each beginsWith:aString. ] ) asOrderedCollection. " Migrate packageNamesStartingWith:'Dolphincompat'. ( Migrate packageNamesStartingWith:'Dolphincompat' ) do:[ :each | PackageOrganizer default unregisterPackageNamed:each. ]. " ! ! !Migrate class methodsFor: 'method execution' stamp: 'BillSchwab 9/16/2011 05:09'! suspectMethodsReport "9-11 - look for orphaned work" Migrate default suspectMethodsReport.! ! !Migrate class methodsFor: 'use-migrate' stamp: 'BillSchwab 2/6/2012 12:45'! buildAnImage "2-12 - this has become a big pain with lots of false starts trying to load configurations. Worse, auto-saving the image after each step backfires in a big way. So, break it down into little atomic pieces, when something succeeds, enjoy it." "2-12 - make the image comfortable." Migrate default setPreferences. "2-12 - these can fail at random, or so it seems. Do each in sequence and save if you dare." Migrate default loadFFI. Migrate default loadSIXX. Migrate default loadODBC. Migrate default loadLDAP. Migrate default loadOSProcess. Migrate default loadOSProcessCommandShell. Migrate default loadCitezen. Migrate default loadSeaside. "2-12 - now for the local stuff." Migrate default loadPackages. ! ! !Migrate class methodsFor: 'use-migrate' stamp: 'BillSchwab 2/6/2012 04:34'! savePackages "9-11 - save Migrate itself and home-grown packages (with a message configured herein)" Migrate default saveMigrate. Migrate default homeGrownPackagesSaveWithMessage:'For building a new image'. ! !