SystemOrganization addCategory: #'Gofer-Core'! SystemOrganization addCategory: #'Gofer-Test'! Notification subclass: #GoferVersionCache instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferVersionCache class methodsFor: 'private' stamp: 'lr 10/2/2009 09:41'! basicVersionsIn: aRepository | versions | versions := OrderedCollection new. aRepository allVersionNames do: [ :each | versions addLast: (GoferVersionReference name: each repository: aRepository) ]. ^ versions! ! !GoferVersionCache class methodsFor: 'public' stamp: 'lr 9/29/2009 21:47'! during: aBlock | cache | cache := Dictionary new. ^ aBlock on: self do: [ :notification | notification resume: cache ]! ! !GoferVersionCache class methodsFor: 'public' stamp: 'lr 9/29/2009 21:45'! versionsIn: aRepository ^ self signal at: aRepository ifAbsentPut: [ self basicVersionsIn: aRepository ]! ! !GoferVersionCache methodsFor: 'accessing' stamp: 'lr 9/28/2009 23:38'! defaultAction ^ Dictionary new! ! !SystemOrganizer methodsFor: '*gofer' stamp: 'dkh 10/12/2009 12:59'! goferClassesInCategory: category ^(self listAtCategoryNamed: category) collect: [:className| Smalltalk at: className]! ! Object subclass: #Gofer instanceVariableNames: 'references repository' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !Gofer commentStamp: 'lr 11/10/2009 10:28' prior: 0! : Gofer, a person who runs errands. Origin 1960s: from go for, i.e. go and fetch. : ''The New Oxford American Dictionary'' !! Synopsis Gofer is a small tool on top of Monticello that loads, updates, merges, diffs, reverts, commits, recompiles and unloads groups of Monticello packages. Contrary to existing tools Gofer makes sure that these operations are performed as clean as possible: - Gofer treats packages from one or more repository in one operation. - Gofer works with fixed versions or tries to find the "latest" version using a given name prefix. - Gofer automatically assigns repositories to all packages, so that the other tools are ready to be used on individual packages. - Gofer makes sure that there is only one repository instance registered for a single physical location. - Gofer works with Monticello dependencies and uniformly treats them like the primary package. - Gofer cleans up after Monticello, no empty class categories and no empty method protocols are to be expected. !! Installation Gofer is included with the latest Pharo and GemStone distributions. To update to the latest version you can use Gofer itself: == Gofer gofer update In case you are missing Gofer in your image, grab it from *http://source.lukas-renggli.ch/gofer.html*. !! Description Gofer is very simple by design, the basic useage scenario is always the same and consists of three steps: # You specify a Monticello repository URL. You can do this using the methods ==url:== or ==url:username:password:== if you need full control, or using convenience methods like ==squeaksource:==, ==wiresong:==, or ==gemsource:== for well known repositories. # You specify one or more Monticello packages you want to work with, by adding them to the Gofer instance. Use ==addVersion:== to add a specific version, or use ==addPackage:== to add the "latest" version in the given repository. Furthermore there is ==addPackage:constraint:== that allows to further constraint the version to be loaded in a block passed in as the second argument. # You specify one or more actions to be performed on the specified packages: | ==load== | Load the specified packages. | ==update== | Update the specified packages. | ==merge== | Merge the specified packages into their working copies. | ==changes== | Display the changes between the specified versions and their working copy. | ==log== | Answer a change log between the specified package versions and the working copy. | ==cleanup== | Cleans the specified packages. | ==commit== | Commit the modified specified packages. | ==commit:== | Commit the modified specified packages with the given commit message. | ==revert== | Revert the specified packages to the currently loaded version. | ==recompile== | Recompile the specified packages. | ==unload== | Unload the specified packages. !! Example To use Gofer to load exact versions of the Kom Server, the 'latest' code of Seaside 2.8 and the 'latest' code of the Scriptaculous package that is committed by the author with the initials 'lr' one could write: == Gofer new == squeaksource: 'KomHttpServer'; == addVersion: 'DynamicBindings-gc.7'; == addVersion: 'KomServices-gc.19'; == addVersion: 'KomHttpServer-gc.32'; == squeaksource: 'Seaside'; == addPackage: 'Seaside2.8a'; == addPackage: 'Scriptaculous' constraint: [ :version | version author = 'lr' ]; == load! !Gofer class methodsFor: 'examples' stamp: 'lr 11/10/2009 09:40'! gofer "Create a Gofer instance of Gofer." ^ self new renggli: 'gofer'; addPackage: 'Gofer'; yourself! ! !Gofer class methodsFor: 'instance creation' stamp: 'lr 11/6/2009 10:50'! it ^ self new! ! !Gofer class methodsFor: 'examples' stamp: 'lr 10/2/2009 10:18'! komanche "Create a Gofer instance of Komanche." ^ self new squeaksource: 'KomHttpServer'; addPackage: 'DynamicBindings'; addPackage: 'KomServices'; addPackage: 'KomHttpServer'; yourself! ! !Gofer class methodsFor: 'examples' stamp: 'lr 10/2/2009 10:18'! magritte "Create a Gofer instance of Magritte." ^ self new renggli: 'magritte'; addPackage: 'Magritte-Model'; addPackage: 'Magritte-Tests'; addPackage: 'Magritte-Seaside'; addPackage: 'Magritte-Morph'; yourself! ! !Gofer class methodsFor: 'instance creation' stamp: 'lr 8/20/2009 09:54'! new ^ self basicNew initialize! ! !Gofer class methodsFor: 'examples' stamp: 'lr 11/10/2009 09:45'! omnibrowser "Create a Gofer instance of OmniBrowser." ^ self new renggli: 'omnibrowser'; addPackage: 'OmniBrowser'; addPackage: 'OB-Standard'; addPackage: 'OB-Morphic'; addPackage: 'OB-Shout'; addPackage: 'OB-Refactory'; addPackage: 'OB-Regex'; addPackage: 'OB-SUnitIntegration'; yourself! ! !Gofer class methodsFor: 'examples' stamp: 'lr 10/2/2009 10:18'! pier "Create a Gofer instance of Pier." ^ self new renggli: 'pier'; addPackage: 'Pier-Model'; addPackage: 'Pier-Tests'; addPackage: 'Pier-Seaside'; addPackage: 'Pier-Blog'; addPackage: 'Pier-Security'; addPackage: 'Pier-Squeak-Persistency'; yourself! ! !Gofer class methodsFor: 'examples' stamp: 'lr 10/2/2009 10:19'! pierAddons "Create a Gofer instance of Pier Addons." ^ self new renggli: 'pieraddons'; addPackage: 'Pier-Design'; addPackage: 'Pier-Documents'; addPackage: 'Pier-EditorEnh'; addPackage: 'Pier-Google'; addPackage: 'Pier-Links'; addPackage: 'Pier-Randomizer'; addPackage: 'Pier-TagCloud'; addPackage: 'Pier-Slideshow'; addPackage: 'Pier-Setup'; yourself! ! !Gofer class methodsFor: 'examples' stamp: 'lr 11/10/2009 09:44'! refactoring "Create a Gofer instance of the refactoring tools." ^ self new squeaksource: 'rb'; addPackage: 'AST-Core'; addPackage: 'AST-Tests'; addPackage: 'Refactoring-Core'; addPackage: 'Refactoring-Tests'; addPackage: 'Refactoring-Spelling'; yourself! ! !Gofer class methodsFor: 'examples' stamp: 'lr 10/28/2009 19:24'! seaside28 "Create a Gofer instance of Seaside 2.8." ^ self new squeaksource: 'Seaside'; addPackage: 'Seaside2.8a1'; addPackage: 'Scriptaculous'; addPackage: 'Comet'; squeaksource: 'rsrss'; addPackage: 'RSRSS2'; yourself! ! !Gofer class methodsFor: 'examples' stamp: 'lr 11/10/2009 09:45'! tools "Create a Gofer instance of several development tools." ^ self new renggli: 'unsorted'; addPackage: 'Shout'; addPackage: 'ShoutWorkspace'; addPackage: 'RoelTyper'; addPackage: 'ECompletion'; addPackage: 'ECompletionOmniBrowser'; yourself! ! !Gofer methodsFor: 'adding' stamp: 'lr 10/12/2009 23:56'! add: aReference "Add aReference to the list of packages." ^ aReference isString ifTrue: [ self notify: 'Please note that adding package references as strings (such as ' , aReference printString , ') is no longer supported, because Gofer cannot guess your naming conventions. Adapt your code to either call #addPackage: (for full package names, e.g. ''Gofer''), #addVersion: (for complete version names, e.g. ''Gofer-lr.54'') or #addQuery:do: (for full package names, e.g. ''Gofer'', with the possiblity to add additional conditions, e.g. reference author: ''lr''; branch: ''super''). This lets Gofer know what exactly you want, and in return it will more likely do what you expect.' ] ifFalse: [ self references addLast: aReference ]! ! !Gofer methodsFor: 'adding' stamp: 'lr 10/12/2009 23:52'! addPackage: aString "Add the package aString to the receiver." ^ self add: (GoferPackageReference name: aString repository: self repository)! ! !Gofer methodsFor: 'adding' stamp: 'lr 10/17/2009 14:26'! addPackage: aString constraint: aOneArgumentBlock "Add the package aString to the receiver, constraint the resulting versions further with aOneArgumentBlock." | reference | reference := GoferConstraintReference name: aString repository: self repository. reference constraintBlock: aOneArgumentBlock. ^ self add: reference! ! !Gofer methodsFor: 'adding' stamp: 'lr 10/12/2009 23:52'! addVersion: aString "Add the version aString to the receiver." ^ self add: (GoferVersionReference name: aString repository: self repository)! ! !Gofer methodsFor: 'actions' stamp: 'lr 11/10/2009 10:06'! changes "Display the changes between the specified versions and their working copy." ^ self execute: GoferChanges! ! !Gofer methodsFor: 'actions' stamp: 'lr 10/3/2009 11:31'! cleanup "Cleans the specified packages." ^ self execute: GoferCleanup! ! !Gofer methodsFor: 'actions' stamp: 'lr 11/10/2009 10:08'! commit "Commit the modified packages." ^ self execute: GoferCommit! ! !Gofer methodsFor: 'actions' stamp: 'lr 11/10/2009 10:08'! commit: aString "Commit the modified packages with the given commit message." ^ self execute: GoferCommit do: [ :operation | operation message: aString ]! ! !Gofer methodsFor: 'repositories' stamp: 'lr 7/10/2009 16:27'! croquet: aString self url: 'http://hedgehog.software.umn.edu:8888/' , aString! ! !Gofer methodsFor: 'private' stamp: 'lr 10/2/2009 10:11'! execute: anOperationClass ^ self execute: anOperationClass do: nil! ! !Gofer methodsFor: 'private' stamp: 'lr 10/2/2009 10:11'! execute: anOperationClass do: aBlock | operation | ^ GoferVersionCache during: [ operation := anOperationClass on: self. aBlock isNil ifFalse: [ aBlock value: operation ]. operation execute ]! ! !Gofer methodsFor: 'repositories' stamp: 'dkh 10/16/2009 10:04'! gemsource: aString self url: 'http://seaside.gemstone.com/ss/' , aString! ! !Gofer methodsFor: 'repositories' stamp: 'lr 7/10/2009 16:27'! impara: aString self url: 'http://source.impara.de/' , aString! ! !Gofer methodsFor: 'initialization' stamp: 'lr 10/2/2009 10:09'! initialize references := OrderedCollection new! ! !Gofer methodsFor: 'actions' stamp: 'lr 11/10/2009 10:05'! load "Load the specified packages." ^ self execute: GoferLoad! ! !Gofer methodsFor: 'actions' stamp: 'lr 11/10/2009 10:10'! log "Answer a change log between the specified package versions and the working copy." ^ self execute: GoferLog! ! !Gofer methodsFor: 'actions' stamp: 'lr 11/10/2009 10:06'! merge "Merge the specified packages into their working copies." ^ self execute: GoferMerge! ! !Gofer methodsFor: 'copying' stamp: 'lr 10/2/2009 10:09'! postCopy super postCopy. references := references copy! ! !Gofer methodsFor: 'actions' stamp: 'lr 8/20/2009 11:44'! recompile "Recompile the specified packages." ^ self execute: GoferRecompile! ! !Gofer methodsFor: 'accessing' stamp: 'lr 10/1/2009 21:08'! references "Answer a list of references." ^ references! ! !Gofer methodsFor: 'repositories' stamp: 'lr 7/10/2009 16:25'! renggli: aString self url: 'http://source.lukas-renggli.ch/' , aString! ! !Gofer methodsFor: 'accessing' stamp: 'lr 10/2/2009 10:08'! repository "Answer a current repository or nil." ^ repository! ! !Gofer methodsFor: 'accessing' stamp: 'lr 10/2/2009 10:21'! repository: aRepository "Set the repository aRepository as the location for the following package additions." MCRepositoryGroup default addRepository: aRepository. repository := MCRepositoryGroup default repositories detect: [ :each | each = aRepository ] ifNone: [ self error: 'Internal error' ]. repository copyFrom: aRepository! ! !Gofer methodsFor: 'actions' stamp: 'lr 8/20/2009 10:15'! revert "Revert the specified packages to the currently loaded version." ^ self execute: GoferRevert! ! !Gofer methodsFor: 'repositories' stamp: 'lr 7/10/2009 16:29'! saltypickle: aString self url: 'http://squeak.saltypickle.com/' , aString! ! !Gofer methodsFor: 'repositories' stamp: 'lr 7/10/2009 16:28'! squeakfoundation: aString self url: 'http://source.squeakfoundation.org/' , aString! ! !Gofer methodsFor: 'repositories' stamp: 'lr 7/10/2009 16:28'! squeaksource: aString self url: 'http://www.squeaksource.com/' , aString! ! !Gofer methodsFor: 'actions' stamp: 'lr 11/10/2009 10:07'! unload "Unload the specified packages." ^ self execute: GoferUnload! ! !Gofer methodsFor: 'actions' stamp: 'lr 9/18/2009 18:12'! update "Update the specified packages." ^ self execute: GoferUpdate! ! !Gofer methodsFor: 'repositories' stamp: 'lr 9/7/2009 20:11'! url: aString "Set the repository URL aString as the location for the following package additions." self url: aString username: String new password: String new! ! !Gofer methodsFor: 'repositories' stamp: 'lr 9/7/2009 20:12'! url: aString username: aUsernameString password: aPasswordString "Set the repository URL aString as the location for the following package additions." self repository: (MCHttpRepository location: aString user: aUsernameString password: aPasswordString)! ! !Gofer methodsFor: 'repositories' stamp: 'lr 7/10/2009 16:26'! wiresong: aString self url: 'http://source.wiresong.ca/' , aString! ! Object subclass: #GoferOperation instanceVariableNames: 'gofer model' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! GoferOperation subclass: #GoferLoad instanceVariableNames: 'versions repositories' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferLoad methodsFor: 'private' stamp: 'lr 10/2/2009 09:57'! addReference: aReference | version | version := aReference versionReference version. version withAllDependenciesDo: [ :dependency | versions addLast: dependency. (repositories at: dependency ifAbsentPut: [ Set new ]) addAll: aReference repositories ]. model addVersion: version! ! !GoferLoad methodsFor: 'private' stamp: 'lr 9/3/2009 11:00'! defaultModel ^ MCVersionLoader new! ! !GoferLoad methodsFor: 'running' stamp: 'dkh 10/12/2009 12:56'! execute self model goferHasVersions ifTrue: [ self model load ]. self updateRepositories. self updateCategories! ! !GoferLoad methodsFor: 'initialization' stamp: 'lr 9/3/2009 11:00'! initialize super initialize. versions := OrderedCollection new. repositories := Dictionary new! ! !GoferLoad methodsFor: 'initialization' stamp: 'lr 10/2/2009 10:14'! initializeOn: aGofer super initializeOn: aGofer. aGofer references do: [ :each | self addReference: each ]! ! !GoferLoad methodsFor: 'private' stamp: 'lr 9/20/2009 13:43'! updateCategories "This method makes sure that the categories are ordered in load-order and as specified in the packages." | categories | categories := OrderedCollection new. versions do: [ :version | version snapshot definitions do: [ :definition | definition isOrganizationDefinition ifTrue: [ definition categories do: [ :category | (categories includes: category) ifFalse: [ categories addLast: category ] ] ] ] ]. (MCOrganizationDefinition categories: categories) postloadOver: nil! ! !GoferLoad methodsFor: 'private' stamp: 'lr 10/3/2009 12:02'! updateRepositories "This code makes sure that all packages have a repository assigned, including the dependencies." repositories keysAndValuesDo: [ :version :collection | collection do: [ :repository | version workingCopy repositoryGroup addRepository: repository ] ]! ! !GoferOperation class methodsFor: 'instance creation' stamp: 'lr 9/3/2009 10:28'! new self shouldNotImplement! ! !GoferOperation class methodsFor: 'instance creation' stamp: 'lr 8/20/2009 12:01'! on: aGofer ^ self basicNew initializeOn: aGofer! ! !GoferOperation methodsFor: 'private' stamp: 'lr 8/19/2009 14:01'! defaultModel ^ nil! ! !GoferOperation methodsFor: 'running' stamp: 'lr 8/17/2009 14:40'! execute "Execute the receiving action." self subclassResponsibility! ! !GoferOperation methodsFor: 'accessing' stamp: 'lr 10/3/2009 11:38'! gofer "Answer the Gofer instance that triggered this operation." ^ gofer! ! !GoferOperation methodsFor: 'initialization' stamp: 'lr 8/19/2009 14:01'! initialize model := self defaultModel! ! !GoferOperation methodsFor: 'initialization' stamp: 'lr 10/3/2009 11:28'! initializeOn: aGofer gofer := aGofer copy. self initialize! ! !GoferOperation methodsFor: 'accessing' stamp: 'lr 8/20/2009 10:13'! model "Answer the Monticello model of this operation." ^ model! ! GoferOperation subclass: #GoferWorking instanceVariableNames: 'workingCopies' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! GoferWorking subclass: #GoferChanges instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferChanges methodsFor: 'private' stamp: 'lr 10/2/2009 10:25'! addReference: aReference requiredCopy: aWorkingCopy repositories: anArray | source target patch | super addReference: aReference requiredCopy: aWorkingCopy repositories: anArray. source := aWorkingCopy package. target := aReference versionReference version. patch := source snapshot patchRelativeToBase: target snapshot. aWorkingCopy modified: patch isEmpty not. self model operations addAll: patch operations! ! !GoferChanges methodsFor: 'private' stamp: 'lr 8/19/2009 14:02'! defaultModel ^ MCPatch operations: OrderedCollection new! ! !GoferChanges methodsFor: 'running' stamp: 'lr 8/19/2009 14:06'! execute self model isEmpty ifFalse: [ self model browse ]! ! GoferWorking subclass: #GoferCleanup instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferCleanup methodsFor: 'cleaning' stamp: 'lr 10/3/2009 11:37'! cleanup: aWorkingCopy self cleanupCategories: aWorkingCopy. self cleanupProtocols: aWorkingCopy! ! !GoferCleanup methodsFor: 'cleaning' stamp: 'dkh 10/12/2009 12:59'! cleanupCategories: aWorkingCopy aWorkingCopy packageInfo systemCategories do: [ :category | (SystemOrganization goferClassesInCategory: category) isEmpty ifTrue: [ SystemOrganization removeSystemCategory: category ] ]! ! !GoferCleanup methodsFor: 'cleaning' stamp: 'lr 10/3/2009 11:37'! cleanupProtocols: aWorkingCopy aWorkingCopy packageInfo extensionClasses do: [ :class | (aWorkingCopy packageInfo extensionCategoriesForClass: class) do: [ :category | (class organization listAtCategoryNamed: category) isEmpty ifTrue: [ class organization removeCategory: category ] ] ]. aWorkingCopy packageInfo classesAndMetaClasses do: [ :class | (aWorkingCopy packageInfo coreCategoriesForClass: class) do: [ :category | (class organization listAtCategoryNamed: category) isEmpty ifTrue: [ class organization removeCategory: category ] ] ]! ! !GoferCleanup methodsFor: 'running' stamp: 'lr 10/3/2009 11:30'! execute self workingCopies do: [ :each | self cleanup: each ]! ! GoferWorking subclass: #GoferCommit instanceVariableNames: 'repositories message' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferCommit methodsFor: 'private' stamp: 'lr 10/2/2009 10:05'! addReference: aPackage requiredCopy: aWorkingCopy repositories: anArray super addReference: aPackage requiredCopy: aWorkingCopy repositories: anArray. repositories at: aWorkingCopy put: anArray! ! !GoferCommit methodsFor: 'running' stamp: 'lr 9/24/2009 17:32'! execute self workingCopies do: [ :workingCopy | workingCopy needsSaving ifTrue: [ self execute: workingCopy ] ]! ! !GoferCommit methodsFor: 'running' stamp: 'lr 10/13/2009 00:29'! execute: aWorkingCopy | targets version | targets := repositories at: aWorkingCopy. targets isEmpty ifTrue: [ self error: 'No repository found for ' , aWorkingCopy packageName printString ]. version := [ aWorkingCopy newVersion ] on: MCVersionNameAndMessageRequest do: [ :notifcation | self message isNil ifTrue: [ message := notifcation outer last ]. notifcation resume: (Array with: notifcation suggestedName with: self message) ]. targets first storeVersion: version! ! !GoferCommit methodsFor: 'initialization' stamp: 'lr 8/20/2009 12:14'! initialize super initialize. repositories := Dictionary new! ! !GoferCommit methodsFor: 'accessing' stamp: 'lr 10/2/2009 10:12'! message ^ message! ! !GoferCommit methodsFor: 'accessing' stamp: 'lr 10/2/2009 10:12'! message: aString message := aString! ! GoferWorking subclass: #GoferLog instanceVariableNames: 'latestVersions' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferLog methodsFor: 'private' stamp: 'lr 10/22/2009 20:36'! addReference: aReference requiredCopy: aWorkingCopy repositories: anArray super addReference: aReference requiredCopy: aWorkingCopy repositories: anArray. latestVersions at: aWorkingCopy put: aReference versionReference version info! ! !GoferLog methodsFor: 'private' stamp: 'lr 11/10/2009 10:23'! allVersionsFrom: aFirstVersion to: aSecondVersion | versions result | versions := (aFirstVersion hasAncestor: aSecondVersion) ifTrue: [ Array with: aFirstVersion with: aSecondVersion ] ifFalse: [ Array with: aSecondVersion with: aFirstVersion ]. result := OrderedCollection with: versions last. versions first = versions last ifFalse: [ versions last breadthFirstAncestors do: [ :version | versions first = version ifTrue: [ ^ result ] ifFalse: [ result addLast: version ] ] ]. ^ result! ! !GoferLog methodsFor: 'running' stamp: 'lr 11/10/2009 10:20'! execute | result currentVersion | result := OrderedCollection new. latestVersions keysAndValuesDo: [ :workingCopy :targetVersion | result addLast: (self allVersionsFrom: workingCopy ancestors first to: targetVersion) ]. ^ result! ! !GoferLog methodsFor: 'initialization' stamp: 'obi 10/3/2009 20:03'! initialize super initialize. latestVersions := Dictionary new! ! GoferWorking subclass: #GoferRecompile instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferRecompile methodsFor: 'running' stamp: 'lr 8/20/2009 11:44'! execute self workingCopies do: [ :copy | self recompile: copy ]! ! !GoferRecompile methodsFor: 'running' stamp: 'lr 8/20/2009 11:47'! recompile: aWorkingCopy aWorkingCopy packageInfo methods do: [ :each | each actualClass recompile: each methodSymbol ]! ! GoferWorking subclass: #GoferUnload instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferUnload methodsFor: 'private' stamp: 'dkh 10/12/2009 13:04'! defaultModel Smalltalk at: #MCMultiPackageLoader ifPresent: [:cl | ^ cl new ]. ^MCPackageLoader new! ! !GoferUnload methodsFor: 'running' stamp: 'lr 10/3/2009 11:45'! execute self workingCopies do: [ :copy | self unload: copy ]. self model load. self gofer cleanup. self workingCopies do: [ :copy | self unregister: copy ]! ! !GoferUnload methodsFor: 'unloading' stamp: 'lr 10/3/2009 11:46'! unload: aWorkingCopy self unloadClasses: aWorkingCopy. self unloadPackage: aWorkingCopy ! ! !GoferUnload methodsFor: 'unloading' stamp: 'nice 10/22/2009 15:14'! unloadClasses: aWorkingCopy aWorkingCopy packageInfo classes do: [ :class | (class includesSelector: #unload) ifTrue: [ class unload ] ]! ! !GoferUnload methodsFor: 'unloading' stamp: 'lr 8/19/2009 14:00'! unloadPackage: aWorkingCopy self model unloadPackage: aWorkingCopy package! ! !GoferUnload methodsFor: 'unregistering' stamp: 'lr 8/19/2009 13:49'! unregister: aWorkingCopy self unregisterWorkingCopy: aWorkingCopy. self unregisterRepositories: aWorkingCopy. self unregisterPackageInfo: aWorkingCopy! ! !GoferUnload methodsFor: 'unregistering' stamp: 'lr 8/19/2009 13:50'! unregisterPackageInfo: aWorkingCopy PackageOrganizer default unregisterPackage: aWorkingCopy packageInfo! ! !GoferUnload methodsFor: 'unregistering' stamp: 'lr 8/19/2009 13:50'! unregisterRepositories: aWorkingCopy aWorkingCopy repositoryGroup repositories allButFirst do: [ :repository | MCWorkingCopy allManagers do: [ :copy | (copy repositoryGroup includes: repository) ifTrue: [ ^ self ] ]. MCRepositoryGroup default removeRepository: repository ]! ! !GoferUnload methodsFor: 'unregistering' stamp: 'lr 8/20/2009 11:54'! unregisterWorkingCopy: aWorkingCopy aWorkingCopy unregister! ! GoferWorking subclass: #GoferUpdate instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! GoferUpdate subclass: #GoferMerge instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferMerge methodsFor: 'private' stamp: 'lr 8/19/2009 14:01'! defaultModel ^ MCVersionMerger new! ! !GoferMerge methodsFor: 'running' stamp: 'lr 10/3/2009 11:39'! execute [ [ self model merge ] on: MCMergeResolutionRequest do: [ :request | request merger conflicts isEmpty ifTrue: [ request resume: true ] ifFalse: [ request pass ] ] ] valueSupplyingAnswers: #(('No Changes' true)). self gofer cleanup! ! GoferUpdate subclass: #GoferRevert instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferRevert methodsFor: 'running' stamp: 'lr 9/19/2009 13:15'! execute self workingCopies do: [ :each | each modified: false ]. super execute! ! !GoferRevert methodsFor: 'private' stamp: 'lr 10/2/2009 10:30'! findVersion: aReference workingCopy: aWorkingCopy repositories: anArray ^ (MCRepositoryGroup withAll: anArray) versionWithInfo: aWorkingCopy ancestors first! ! !GoferUpdate methodsFor: 'private' stamp: 'lr 10/2/2009 10:30'! addReference: aReference workingCopy: aWorkingCopy repositories: anArray super addReference: aReference workingCopy: aWorkingCopy repositories: anArray. self model addVersion: (self findVersion: aReference workingCopy: aWorkingCopy repositories: anArray)! ! !GoferUpdate methodsFor: 'private' stamp: 'lr 9/18/2009 18:13'! defaultModel ^ MCVersionLoader new! ! !GoferUpdate methodsFor: 'running' stamp: 'dkh 10/12/2009 12:55'! execute self model goferHasVersions ifTrue: [ self model load ]. self gofer cleanup! ! !GoferUpdate methodsFor: 'private' stamp: 'lr 10/2/2009 10:27'! findVersion: aReference workingCopy: aWorkingCopy repositories: anArray ^ aReference versionReference version! ! !GoferWorking methodsFor: 'private' stamp: 'lr 10/2/2009 10:22'! addReference: aReference self addReference: aReference workingCopy: aReference workingCopy repositories: aReference repositories! ! !GoferWorking methodsFor: 'private' stamp: 'lr 10/2/2009 10:04'! addReference: aPackage requiredCopy: aWorkingCopy repositories: anArray (workingCopies includes: aWorkingCopy) ifTrue: [ ^ self ]. workingCopies addLast: aWorkingCopy. aWorkingCopy requiredPackages reverseDo: [ :each | self addReference: aPackage requiredCopy: each workingCopy repositories: anArray ]! ! !GoferWorking methodsFor: 'private' stamp: 'lr 10/2/2009 10:06'! addReference: aPackage workingCopy: aWorkingCopy repositories: anArray self addReference: aPackage requiredCopy: aWorkingCopy repositories: anArray! ! !GoferWorking methodsFor: 'initialization' stamp: 'lr 8/19/2009 13:14'! initialize super initialize. workingCopies := OrderedCollection new! ! !GoferWorking methodsFor: 'initialization' stamp: 'lr 10/2/2009 10:12'! initializeOn: aGofer super initializeOn: aGofer. aGofer references do: [ :each | self addReference: each ]! ! !GoferWorking methodsFor: 'accessing' stamp: 'lr 9/24/2009 16:55'! workingCopies "Answer the working copies to be operated on." ^ workingCopies! ! Object subclass: #GoferReference instanceVariableNames: 'repository' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! GoferReference subclass: #GoferPackageReference instanceVariableNames: 'packageName' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferPackageReference commentStamp: 'lr 10/17/2009 14:17' prior: 0! A GoferPackageReference refers to the latest version of a Monticello package within a specified group of repositories.! GoferPackageReference subclass: #GoferConstraintReference instanceVariableNames: 'constraintBlock' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferConstraintReference methodsFor: 'accessing' stamp: 'lr 10/17/2009 14:25'! constraintBlock: aOneArgumentBlock constraintBlock := aOneArgumentBlock! ! !GoferConstraintReference methodsFor: 'initialization' stamp: 'lr 10/17/2009 14:25'! initialize super initialize. self constraintBlock: [ :author | true ]! ! !GoferConstraintReference methodsFor: 'private' stamp: 'lr 10/17/2009 14:25'! matchesVersionReference: aVersionReference ^ (super matchesVersionReference: aVersionReference) and: [ constraintBlock value: aVersionReference ]! ! !GoferPackageReference methodsFor: 'private' stamp: 'lr 10/13/2009 00:00'! matchesVersionReference: aVersionReference ^ self packageName = aVersionReference packageName! ! !GoferPackageReference methodsFor: 'accessing' stamp: 'lr 10/12/2009 23:41'! packageName ^ packageName! ! !GoferPackageReference methodsFor: 'initialization' stamp: 'lr 10/12/2009 23:41'! setName: aString packageName := aString! ! !GoferPackageReference methodsFor: 'accessing' stamp: 'lr 10/13/2009 00:00'! versionReference | versions | versions := self findVersions: [ :each | self matchesVersionReference: each ]. versions isEmpty ifTrue: [ self error: 'No versions for package ' , self packageName printString , ' found.' ]. ^ versions last! ! !GoferReference class methodsFor: 'instance-creation' stamp: 'lr 10/12/2009 23:37'! name: aString ^ self new setName: aString! ! !GoferReference class methodsFor: 'instance-creation' stamp: 'lr 10/2/2009 09:41'! name: aString repository: aRepository ^ (self name: aString) setRepository: aRepository! ! !GoferReference methodsFor: 'utilities' stamp: 'lr 10/12/2009 23:40'! findVersions: aBlock "Answer a sorted array of version references that match aBlock." | versions | versions := SortedCollection new. self repositories do: [ :repo | (GoferVersionCache versionsIn: repo) do: [ :version | (aBlock value: version) ifTrue: [ versions add: version ] ] ]. ^ versions asArray! ! !GoferReference methodsFor: 'private' stamp: 'lr 10/12/2009 23:44'! matchesWorkingCopy: aWorkingCopy ^ self packageName = aWorkingCopy packageName! ! !GoferReference methodsFor: 'accessing' stamp: 'lr 10/12/2009 23:42'! packageName "Answer the package name." self subclassResponsibility! ! !GoferReference methodsFor: 'accessing' stamp: 'lr 10/2/2009 10:56'! repositories "Answer an ordered collection of repositories." | repositories | repositories := OrderedCollection new. self repository isNil ifTrue: [ self workingCopy isNil ifFalse: [ repositories addAll: self workingCopy repositoryGroup repositories ] ] ifFalse: [ self repository isRepositoryGroup ifFalse: [ repositories add: self repository ] ifTrue: [ repositories addAll: self repository repositories ] ]. repositories := repositories select: [ :each | each isValid and: [ each ~= MCCacheRepository default ] ]. ^ repositories! ! !GoferReference methodsFor: 'accessing' stamp: 'lr 10/12/2009 23:39'! repository "Answer the configured repository." ^ repository! ! !GoferReference methodsFor: 'initialization' stamp: 'lr 10/12/2009 23:36'! setName: aString self subclassResponsibility! ! !GoferReference methodsFor: 'initialization' stamp: 'lr 10/1/2009 19:39'! setRepository: aRepository repository := aRepository! ! !GoferReference methodsFor: 'accessing' stamp: 'lr 10/1/2009 20:05'! versionReference "Answer a version reference that can be directly operated on." self subclassResponsibility! ! !GoferReference methodsFor: 'accessing' stamp: 'lr 10/12/2009 23:44'! workingCopy "Answer a working copy, or nil if the package is not loaded." ^ MCWorkingCopy allManagers detect: [ :each | self matchesWorkingCopy: each ] ifNone: [ nil ]! ! GoferReference subclass: #GoferVersionReference instanceVariableNames: 'fullName packageName authorName branchName versionNumber' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Core'! !GoferVersionReference commentStamp: 'lr 10/17/2009 14:18' prior: 0! A GoferVersionReference refers to a specific version of a Monticello package.! !GoferVersionReference methodsFor: 'comparing' stamp: 'lr 10/1/2009 21:02'! <= aVersion ^ self packageName = aVersion packageName ifFalse: [ self packageName <= aVersion packageName ] ifTrue: [ self versionNumber <= aVersion versionNumber ]! ! !GoferVersionReference methodsFor: 'accessing' stamp: 'lr 10/1/2009 21:01'! authorName "Answer the author name of this version." ^ authorName! ! !GoferVersionReference methodsFor: 'accessing' stamp: 'lr 10/13/2009 00:13'! branchName "Answer the branch name of this version." ^ branchName! ! !GoferVersionReference methodsFor: 'accessing' stamp: 'lr 10/12/2009 23:43'! fullName "Answer the full name of this version." ^ fullName! ! !GoferVersionReference methodsFor: 'accessing' stamp: 'lr 10/1/2009 21:01'! packageName "Answer the package name of this version." ^ packageName! ! !GoferVersionReference methodsFor: 'initialization' stamp: 'lr 11/1/2009 15:50'! setName: aString | name | name := aString last isDigit ifTrue: [ aString ] ifFalse: [ (aString copyUpToLast: $.) copyUpTo: $( ]. fullName := aString. packageName := name copyUpToLast: $-. authorName := (name copyAfterLast: $-) copyUpTo: $.. versionNumber := ((name copyAfterLast: $-) copyAfter: $.). versionNumber isEmpty ifTrue: [ branchName := ''. versionNumber := 0 ] ifFalse: [ (versionNumber allSatisfy: [ :each | each isDigit ]) ifTrue: [ branchName := ''. versionNumber := versionNumber asInteger ] ifFalse: [ branchName := versionNumber copyUpToLast: $.. versionNumber := (versionNumber copyAfterLast: $.) asInteger ] ]! ! !GoferVersionReference methodsFor: 'accessing' stamp: 'lr 10/13/2009 00:22'! version "Answer the Monticello version of the receiver." ^ self repository loadVersionFromFileNamed: self fullName , '.mcz'! ! !GoferVersionReference methodsFor: 'accessing' stamp: 'lr 10/1/2009 21:02'! versionNumber "Answer the version number of this version." ^ versionNumber! ! !GoferVersionReference methodsFor: 'accessing' stamp: 'lr 10/1/2009 19:56'! versionReference ^ self! ! !MCRepository methodsFor: '*gofer-testing' stamp: 'lr 9/24/2009 17:02'! isRepositoryGroup ^ false! ! !MCVersionLoader methodsFor: '*gofer' stamp: 'dkh 10/12/2009 12:54'! goferHasVersions ^ versions isEmpty not! ! !MCRepositoryGroup class methodsFor: '*gofer-core' stamp: 'lr 10/2/2009 10:29'! withAll: anArray ^ anArray inject: self new into: [ :group :repo | group addRepository: repo ]! ! !MCRepositoryGroup methodsFor: '*gofer-testing' stamp: 'lr 9/24/2009 17:01'! isRepositoryGroup ^ true! ! TestCase subclass: #GoferTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Test'! GoferTest subclass: #GoferApiTest instanceVariableNames: 'gofer' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Test'! !GoferApiTest methodsFor: 'running' stamp: 'lr 10/1/2009 21:59'! setUp super setUp. gofer := Gofer new! ! !GoferApiTest methodsFor: 'testing-repositories' stamp: 'lr 10/1/2009 21:59'! testCroquet gofer croquet: 'Hermes'. self assert: gofer repository locationWithTrailingSlash = 'http://hedgehog.software.umn.edu:8888/Hermes/'! ! !GoferApiTest methodsFor: 'testing-repositories' stamp: 'dkh 10/16/2009 11:02'! testGemsource gofer gemsource: 'Seaside29'. self assert: gofer repository locationWithTrailingSlash = 'http://seaside.gemstone.com/ss/Seaside29/'! ! !GoferApiTest methodsFor: 'testing-repositories' stamp: 'lr 10/1/2009 21:59'! testImpara gofer impara: 'Tweak'. self assert: gofer repository locationWithTrailingSlash = 'http://source.impara.de/Tweak/'! ! !GoferApiTest methodsFor: 'testing' stamp: 'lr 10/1/2009 22:03'! testInitialized self assert: gofer repository isNil. self assert: gofer references isEmpty! ! !GoferApiTest methodsFor: 'testing-repositories' stamp: 'lr 10/1/2009 21:59'! testRenggli gofer renggli: 'pier'. self assert: gofer repository locationWithTrailingSlash = 'http://source.lukas-renggli.ch/pier/'! ! !GoferApiTest methodsFor: 'testing-accessing' stamp: 'lr 10/1/2009 21:59'! testRepository gofer repository: MCDirectoryRepository new. self assert: (gofer repository isKindOf: MCDirectoryRepository)! ! !GoferApiTest methodsFor: 'testing-repositories' stamp: 'lr 10/1/2009 21:59'! testSaltypickle gofer saltypickle: 'GraphViz'. self assert: gofer repository locationWithTrailingSlash = 'http://squeak.saltypickle.com/GraphViz/'! ! !GoferApiTest methodsFor: 'testing-repositories' stamp: 'lr 10/1/2009 21:59'! testSqueakfoundation gofer squeakfoundation: '39a'. self assert: gofer repository locationWithTrailingSlash = 'http://source.squeakfoundation.org/39a/'! ! !GoferApiTest methodsFor: 'testing-repositories' stamp: 'lr 10/1/2009 21:59'! testSqueaksource gofer squeaksource: 'Seaside29'. self assert: gofer repository locationWithTrailingSlash = 'http://www.squeaksource.com/Seaside29/'! ! !GoferApiTest methodsFor: 'testing-accessing' stamp: 'lr 10/1/2009 21:59'! testUrl gofer url: 'http://source.lukas-renggli.ch/pier'. self assert: (gofer repository isKindOf: MCHttpRepository). self assert: (gofer repository locationWithTrailingSlash = 'http://source.lukas-renggli.ch/pier/'). self assert: (gofer repository user isEmpty). self assert: (gofer repository password isEmpty)! ! !GoferApiTest methodsFor: 'testing-accessing' stamp: 'lr 10/1/2009 21:59'! testUrlUsernamePassword gofer url: 'http://source.lukas-renggli.ch/pier' username: 'foo' password: 'bar'. self assert: (gofer repository isKindOf: MCHttpRepository). self assert: (gofer repository locationWithTrailingSlash = 'http://source.lukas-renggli.ch/pier/'). self assert: (gofer repository user = 'foo'). self assert: (gofer repository password = 'bar')! ! !GoferApiTest methodsFor: 'testing-repositories' stamp: 'lr 10/1/2009 21:59'! testWiresong gofer wiresong: 'ob'. self assert: gofer repository locationWithTrailingSlash = 'http://source.wiresong.ca/ob/'! ! GoferTest subclass: #GoferReferenceTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Test'! !GoferReferenceTest methodsFor: 'testing' stamp: 'lr 10/2/2009 09:43'! testPackageShouldFindLatestVersion | packageReference versionReference | packageReference := GoferPackageReference name: 'Gofer' repository: self goferRepository. versionReference := packageReference versionReference. self assert: versionReference packageName = 'Gofer'. self assert: versionReference versionNumber > 55! ! !GoferReferenceTest methodsFor: 'testing' stamp: 'lr 10/2/2009 09:48'! testPackageShouldFindWorkingCopy | packageReference workingCopy | packageReference := GoferPackageReference name: 'Gofer'. workingCopy := packageReference workingCopy. self assert: workingCopy packageName = 'Gofer'! ! !GoferReferenceTest methodsFor: 'testing' stamp: 'lr 10/17/2009 14:27'! testQueryShouldFindLatestVersion | queryReference versionReference | queryReference := GoferConstraintReference name: 'Gofer' repository: self goferRepository. versionReference := queryReference versionReference. self assert: versionReference packageName = 'Gofer'. self assert: versionReference versionNumber > 20. self assert: versionReference branchName = ''. queryReference constraintBlock: [ :ref | ref versionNumber < 20 ]. versionReference := queryReference versionReference. self assert: versionReference packageName = 'Gofer'. self assert: versionReference versionNumber = 19. self assert: versionReference authorName = 'lr'. self assert: versionReference branchName = ''. queryReference constraintBlock: [ :ref | ref versionNumber < 20 and: [ ref authorName = 'tg' ] ]. versionReference := queryReference versionReference. self assert: versionReference packageName = 'Gofer'. self assert: versionReference versionNumber = 10. self assert: versionReference authorName = 'tg'. self assert: versionReference branchName = '' ! ! !GoferReferenceTest methodsFor: 'testing' stamp: 'lr 10/17/2009 14:24'! testQueryShouldFindWorkingCopy | queryReference workingCopy | queryReference := GoferConstraintReference name: 'Gofer'. workingCopy := queryReference workingCopy. self assert: workingCopy packageName = 'Gofer'! ! !GoferReferenceTest methodsFor: 'testing-accessing' stamp: 'lr 10/17/2009 14:24'! testShouldKnowPackageName | package | package := GoferPackageReference name: 'Gofer'. self assert: package packageName = 'Gofer'. package := GoferConstraintReference name: 'Gofer'. self assert: package packageName = 'Gofer'. package := GoferVersionReference name: 'Gofer-lr.34'. self assert: package packageName = 'Gofer'! ! !GoferReferenceTest methodsFor: 'testing-accessing' stamp: 'lr 10/17/2009 14:24'! testShouldKnowRepository | package | package := GoferPackageReference name: 'Gofer' repository: self goferRepository. self assert: package repository locationWithTrailingSlash = 'http://source.lukas-renggli.ch/flair/'. package := GoferConstraintReference name: 'Gofer' repository: self goferRepository. self assert: package repository locationWithTrailingSlash = 'http://source.lukas-renggli.ch/flair/'. package := GoferVersionReference name: 'Gofer-lr.34' repository: self goferRepository. self assert: package repository locationWithTrailingSlash = 'http://source.lukas-renggli.ch/flair/'! ! !GoferReferenceTest methodsFor: 'testing' stamp: 'lr 10/2/2009 09:51'! testVersionShouldFindLatestVersion | versionReference otherReference | versionReference := GoferVersionReference name: 'Gofer-lr.18' repository: self goferRepository. otherReference := versionReference versionReference. self assert: versionReference packageName = 'Gofer'. self assert: versionReference authorName = 'lr'. self assert: versionReference versionNumber = 18. self assert: otherReference = versionReference. self assert: otherReference == versionReference! ! !GoferReferenceTest methodsFor: 'testing' stamp: 'lr 10/2/2009 09:51'! testVersionShouldFindWorkingCopy | versionReference workingCopy | versionReference := GoferVersionReference name: 'Gofer-lr.18' repository: self goferRepository. workingCopy := versionReference workingCopy. self assert: workingCopy packageName = 'Gofer'! ! !GoferReferenceTest methodsFor: 'testing' stamp: 'lr 11/1/2009 15:52'! testVersionShouldParseComplexName | queryReference | queryReference := GoferVersionReference name: 'Seaside2.8b5'. self assert: queryReference packageName = 'Seaside2.8b5'. self assert: queryReference authorName = ''. self assert: queryReference branchName = ''. self assert: queryReference versionNumber = 0. queryReference := GoferVersionReference name: 'Seaside2.8b5-avi.1'. self assert: queryReference packageName = 'Seaside2.8b5'. self assert: queryReference authorName = 'avi'. self assert: queryReference branchName = ''. self assert: queryReference versionNumber = 1. queryReference := GoferVersionReference name: 'Seaside-Core-pmm.2'. self assert: queryReference packageName = 'Seaside-Core'. self assert: queryReference authorName = 'pmm'. self assert: queryReference branchName = ''. self assert: queryReference versionNumber = 2. queryReference := GoferVersionReference name: 'Seaside-Core-jf.configcleanup.3'. self assert: queryReference packageName = 'Seaside-Core'. self assert: queryReference authorName = 'jf'. self assert: queryReference branchName = 'configcleanup'. self assert: queryReference versionNumber = 3. queryReference := GoferVersionReference name: 'Seaside-Core-lr.configcleanup.extraspeedup.69'. self assert: queryReference packageName = 'Seaside-Core'. self assert: queryReference authorName = 'lr'. self assert: queryReference branchName = 'configcleanup.extraspeedup'. self assert: queryReference versionNumber = 69. queryReference := GoferVersionReference name: 'Seaside-Core-lr.configcleanup42.extraspeedup.69'. self assert: queryReference packageName = 'Seaside-Core'. self assert: queryReference authorName = 'lr'. self assert: queryReference branchName = 'configcleanup42.extraspeedup'. self assert: queryReference versionNumber = 69. ! ! GoferTest subclass: #GoferScenarioTest instanceVariableNames: 'gofer' classVariableNames: '' poolDictionaries: '' category: 'Gofer-Test'! !GoferScenarioTest methodsFor: 'assertions' stamp: 'lr 8/20/2009 20:58'! assertClass: aClassSymbol self assert: (Smalltalk hasClassNamed: aClassSymbol)! ! !GoferScenarioTest methodsFor: 'assertions' stamp: 'lr 8/20/2009 21:04'! assertClass: aClassSymbol selector: aMethodSymbol self assertClass: aClassSymbol. self assert: ((Smalltalk at: aClassSymbol) includesSelector: aMethodSymbol)! ! !GoferScenarioTest methodsFor: 'utilities' stamp: 'lr 8/20/2009 21:03'! compile: aClassSelector method: aString self assertClass: aClassSelector. (Smalltalk at: aClassSelector) compile: aString.! ! !GoferScenarioTest methodsFor: 'utilities' stamp: 'lr 8/20/2009 21:04'! evaluate: aClassSelector selector: aMethodSelector self assertClass: aClassSelector selector: aMethodSelector. ^ (Smalltalk at: aClassSelector) new perform: aMethodSelector! ! !GoferScenarioTest methodsFor: 'utilities' stamp: 'lr 8/20/2009 21:14'! hasPackage: aString | package | package := MCWorkingCopy allManagers detect: [ :each | each packageName = aString ] ifNone: [ nil ]. ^ package notNil! ! !GoferScenarioTest methodsFor: 'running' stamp: 'dkh 10/16/2009 10:02'! setUp gofer := Gofer new. gofer gemsource: 'bogus'; addPackage: 'BogusInfo'! ! !GoferScenarioTest methodsFor: 'running' stamp: 'lr 8/20/2009 21:12'! tearDown [ gofer unload ] on: Error do: [ :err | "assume it is not there" ]! ! !GoferScenarioTest methodsFor: 'testing' stamp: 'lr 9/28/2009 23:39'! testCommit "dunno how to test yet"! ! !GoferScenarioTest methodsFor: 'testing' stamp: 'lr 9/28/2009 23:39'! testDiff "dunno how to test yet"! ! !GoferScenarioTest methodsFor: 'testing' stamp: 'lr 8/20/2009 21:15'! testLoad self shouldnt: [ gofer load ] raise: Error. self assert: (self hasPackage: 'Bogus'); assertClass: #BogusA. self assert: (self hasPackage: 'BogusExt'); assertClass: #BogusA selector: #isFake. self assert: (self hasPackage: 'BogusInfo'); assertClass: #BogusInfo! ! !GoferScenarioTest methodsFor: 'testing' stamp: 'lr 9/28/2009 23:40'! testMerge "dunno how to test yet"! ! !GoferScenarioTest methodsFor: 'testing' stamp: 'lr 8/20/2009 21:13'! testRecompile gofer load. self shouldnt: [ gofer recompile ] raise: Error! ! !GoferScenarioTest methodsFor: 'testing' stamp: 'lr 8/20/2009 21:09'! testRevert gofer load. self assert: (self evaluate: #BogusA selector: #isFake). self compile: #BogusA method: 'isFake ^ false'. self deny: (self evaluate: #BogusA selector: #isFake). self shouldnt: [ gofer revert ] raise: Error. self assert: (self evaluate: #BogusA selector: #isFake)! ! !GoferScenarioTest methodsFor: 'testing' stamp: 'lr 8/20/2009 21:15'! testUnload gofer load. self shouldnt: [ gofer unload ] raise: Error. self deny: (self hasPackage: 'Bogus'). self deny: (self hasPackage: 'BogusExt'). self deny: (self hasPackage: 'BogusInfo')! ! !GoferScenarioTest methodsFor: 'testing' stamp: 'lr 9/19/2009 14:13'! testUpdate gofer load. self shouldnt: [ gofer update ] raise: Error. self assert: (self hasPackage: 'Bogus'). self assert: (self hasPackage: 'BogusExt'). self assert: (self hasPackage: 'BogusInfo')! ! !GoferTest class methodsFor: 'testing' stamp: 'lr 10/1/2009 22:00'! isAbstract ^ self name = #GoferTest! ! !GoferTest class methodsFor: 'accessing' stamp: 'lr 10/1/2009 21:53'! packageNamesUnderTest ^ #('Gofer')! ! !GoferTest methodsFor: 'accessing' stamp: 'lr 10/1/2009 21:58'! bogusRepository ^ MCHttpRepository location: 'http://source.wiresong.ca/ob' user: '' password: ''! ! !GoferTest methodsFor: 'accessing' stamp: 'lr 10/1/2009 21:58'! goferRepository ^ MCHttpRepository location: 'http://source.lukas-renggli.ch/flair' user: '' password: ''! ! !GoferTest methodsFor: 'running' stamp: 'lr 10/1/2009 21:59'! runCase GoferVersionCache during: [ super runCase ]! !