Gofer

Gofer
: 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 prefers to work with faster repositories if there is a choice.
- 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:==, ==url:username:password:== (HTTP, FTP), or ==directory:== if you need full control, or using convenience methods like ==squeaksource:==, ==wiresong:==, or ==gemsource:== for well known repositories. Additionally the following settings are available:
#- Gofer implicitly declares the local package cache as a repository. To disable the local package cache use the method ==disablePackageCache==, to re-enable use ==enablePackageCache==.
#- Gofer throws Gofer throws errors if a repository is not reachable. To silently ignore repository erros use the message ==disableRepositoryErrors==, to re-enable use ==enableRepositoryErrors==.
# You specify one or more Monticello packages you want to work with, by adding them to the Gofer instance. Use ==version:== to add a specific version, or use ==package:== to add the "latest" version in the given repository. Furthermore there is ==package: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.
| ==localChanges== | Display the changes between the base version and the working copy.
| ==remoteChanges== | Display the changes between the working copy and the remote changes.
| ==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.
| ==fetch== | Download versions from remote repositories into the local cache.
| ==push== | Upload local versions from local cache into remote repositories.
! 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';
== version: 'DynamicBindings-gc.7';
== version: 'KomServices-gc.19';
== version: 'KomHttpServer-gc.32';
== squeaksource: 'Seaside';
== package: 'Seaside2.8a';
== package: 'Scriptaculous' constraint: [ :version | version author = 'lr' ];
== load
addPackage:
addPackage:constraint:
addVersion:
allResolved
Answer all sorted references within the configured repositories.
allResolvedIn:
Answer all sorted references within aRepository. For efficiency cache the references.
basicReferencesIn:
browseLocalChanges
Browse the changes between the base version and the working copy.
browseRemoteChanges
Browse the changes between the working copy and the remote changes.
cleanup
Cleans the specified packages.
commit
Commit the modified packages.
commit:
Commit the modified packages with the given commit message.
croquet:
directory:
Add a file-system repository at aDirectoryOrString.
disablePackageCache
Disable the use of the package-cache repository.
disableRepositoryErrors
Silently swallow all repository errors.
enablePackageCache
Enable the use of the package-cache repository.
enableRepositoryErrors
Throw an exception when repositories are not available.
execute:
execute:do:
fetch
Download versions from remote repositories into the local cache.
gemsource:
gofer
impara:
initialize
Subclasses should redefine this method to perform initializations on instance creation
it
load
Load the specified packages into the image.
localChanges
Answer the changes between the base version and the working copy.
merge
Merge the specified packages into their working copies.
new
package:
Add the package aString to the receiver.
package:constraint:
Add the package aString to the receiver, constraint the resulting versions further with aOneArgumentBlock.
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
push
Upload local versions from local cache into remote repositories.
recompile
Recompile the specified packages.
references
Answer the configured references.
reinitialize
Calls the class side initializers on all package code.
remoteChanges
Display the changes between the working copy and the remote changes.
renggli:
repositories
Answer the configured monticello repositories.
repository:
Add aRepository to the repository configuration. If there is already a repository defined in the global configuration with that URL take this one instead.
resolved
Answer the resolved references of the receiver.
revert
Revert the specified packages to the currently loaded version.
saltypickle:
squeakfoundation:
squeaksource:
unload
Unload the specified packages.
update
Update the specified packages.
upgrade
url:
Add anUrlString as a repository for the following package operations.
url:username:password:
Add anUrlString as a repository for the following package operations.
version:
Add the version aString to the receiver.
wiresong:
GoferApiTest
A GoferApiTest is xxxxxxxxx.
Instance Variables
assert:repositories:
testConstraintReference
testCroquet
testCustomRepository
testDirectoryRepository
testFtpRepository
testGemsource
testHttpRepository
testImpara
testInitialReferences
testInitialRepositories
testPackageCache
testPackageReference
testRenggli
testRepositoryErrors
testSaltypickle
testSqueakfoundation
testSqueaksource
testSubDirectoryRepository
testVersionReference
testWiresong
GoferBrowseLocalChanges
A GoferBrowseLocalChanges is xxxxxxxxx.
Instance Variables
execute
Execute the receiving action.
GoferBrowseRemoteChanges
A GoferBrowseRemoteChanges is xxxxxxxxx.
Instance Variables
execute
Execute the receiving action.
GoferChanges
A GoferChanges is xxxxxxxxx.
Instance Variables
addReference:
defaultModel
execute
Execute the receiving action.
patchsetOf:
Answer the source snapshot of aReference.
sourceSnapshotOf:
Answer the source snapshot of aReference.
targetSnapshotOf:
Answer the source snapshot of aReference.
GoferCleanup
A GoferCleanup is xxxxxxxxx.
Instance Variables
cleanup:
cleanupCategories:
cleanupProtocols:
execute
Execute the receiving action.
GoferCommit
A GoferCommit is xxxxxxxxx.
Instance Variables
message: <Object>
message
- xxxxx
execute
Execute the receiving action.
execute:
initializeOn:
message
message:
GoferConstraintReference
A GoferPackageReference refers to the latest version of a Monticello package satisfying an additional set of conditions.
initializeName:constraint:
matches:
Answer true if the receiver matches aLoadableReference.
name:constraint:
GoferFetch
A GoferFetch is xxxxxxxxx.
Instance Variables
defaultModel
execute
Execute the receiving action.
initializeOn:
GoferLoad
A GoferLoad is xxxxxxxxx.
Instance Variables
addResolved:
defaultModel
execute
Execute the receiving action.
initializeOn:
updateCategories
This method makes sure that the categories are ordered in load-order and as specified in the packages.
updateRepositories
This code makes sure that all packages have a repository assigned, including the dependencies.
versions
GoferLocalChanges
A GoferLocalChanges is xxxxxxxxx.
Instance Variables
sourceSnapshotOf:
Answer the source snapshot of aReference.
targetSnapshotOf:
Answer the source snapshot of aReference.
GoferMerge
A GoferMerge is xxxxxxxxx.
Instance Variables
defaultModel
execute
Execute the receiving action.
GoferOperation
A GoferOperation is xxxxxxxxx.
Instance Variables
gofer: <Object>
model: <Object>
gofer
- xxxxx
model
- xxxxx
defaultModel
execute
Execute the receiving action.
gofer
Answer the Gofer instance that triggered this operation.
initialize
Subclasses should redefine this method to perform initializations on instance creation
initializeOn:
model
Answer the Monticello model of this operation.
new
on:
GoferOperationTest
A GoferOperationTest is xxxxxxxxx.
Instance Variables
hasClass:
hasClass:selector:
hasPackage:
hasVersion:
setUp
tearDown
testCleanup
testCommit
testFetch
testLoad
testLocalChanges
testMerge
testPush
testRecompile
testReinitialize
testRemoteChanges
testRevert
testUnload
testUpdate
GoferPackageReference
A GoferPackageReference refers to the latest version of a Monticello package.
matches:
Answer true if the receiver matches aLoadableReference.
packageName
Answer the package name.
GoferPush
A GoferPush is xxxxxxxxx.
Instance Variables
defaultModel
execute
Execute the receiving action.
initializeOn:
GoferRecompile
A GoferRecompile is xxxxxxxxx.
Instance Variables
execute
Execute the receiving action.
execute:
GoferReference
A GoferReference is xxxxxxxxx.
Instance Variables
name: <Object>
name
- xxxxx
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
hash
Answer a SmallInteger whose value is related to the receiver's identity.
May be overridden, and should be overridden in any classes that define =
initializeName:
matches:
Answer true if the receiver matches aLoadableReference.
name
Answer the name of this reference.
name:
new
packageName
Answer the package name.
printOn:
Append to the argument, aStream, a sequence of characters that
identifies the receiver.
resolveAllWith:
Answer a sorted collection of all resolved references within aGofer.
resolveWith:
Answer a single resolved reference with aGofer configuration, throw an error if the version can't be found.'
workingCopy
Answer a working copy or throw an error if not present.
GoferReferenceTest
A GoferReferenceTest is xxxxxxxxx.
Instance Variables
setUp
testContraintShouldFindLatestVersion
testContraintShouldFindWorkingCopy
testLoadableShouldSortCorrectly
testPackageShouldFindLatestVersion
testPackageShouldFindWorkingCopy
testResolvedShouldFindLatestVersion
testResolvedShouldFindWorkingCopy
testVersionShouldFindLatestVersion
testVersionShouldFindWorkingCopy
testVersionShouldParseComplexName
GoferReinitialize
A GoferReinitialize is xxxxxxxxx.
Instance Variables
execute
Execute the receiving action.
execute:
GoferRemoteChanges
A GoferRemoteChanges is xxxxxxxxx.
Instance Variables
sourceSnapshotOf:
Answer the source snapshot of aReference.
targetSnapshotOf:
Answer the source snapshot of aReference.
GoferRepositoryError
A GoferRepositoryError is xxxxxxxxx.
Instance Variables
repository: <Object>
repository
- xxxxx
isResumable
Determine whether an exception is resumable.
repository
repository:
signal:repository:
GoferResolvedReference
A GoferVersionReference refers to a specific version of a Monticello package in a particular repository. This class is the only one that can actually access the version, because it is the only one knowing where to find it.
<=
Sort versions according to:
1. package name
2. branch name, list versions without branch last
3. version number
4. author name
5. repository priority
asMetacelloCachingResolvedReference
initializeName:repository:
name:repository:
repository
Answer the repository of the receiver.
version
Answer a Monticello version of the receiver.
GoferResource
A GoferResource is xxxxxxxxx.
Instance Variables
monticelloRepository: <Object>
versionReferences: <Object>
monticelloRepository
- xxxxx
versionReferences
- xxxxx
monticelloRepository
setUp
Does nothing. Subclasses should override this
to initialize their resource
setUpMonticelloRepository
This method builds a fake repository with the version references from #buildReferences.
setUpVersionReferences
This method answers a set of Gofer references in the order they should be sorted. It includes two different packages (Gofer-Foo, Gofer-Bar), linear series of packages (Gofer-Foo-lr.1, Gofer-Foo-lr.2, Gofer-Foo-lr.4), packages with a branch (Gofer-Bar-lr.branch.1,Gofer-Bar-lr.branch.2), and packages with the same version but different authors (Gofer-Bar-jf.1, Gofer-Bar-lr.1).
versionReferences
GoferRevert
A GoferRevert is xxxxxxxxx.
Instance Variables
execute
Execute the receiving action.
referenceFor:
GoferSynchronize
A GoferSynchronize is xxxxxxxxx.
Instance Variables
cacheReferences: <Object>
cacheReferences
- xxxxx
cacheRepository
initializeOn:
GoferTest
A GoferTest is xxxxxxxxx.
Instance Variables
gofer: <Object>
gofer
- xxxxx
isAbstract
monticelloRepository
packageNamesUnderTest
resources
setUp
versionReferences
GoferUnload
A GoferUnload is xxxxxxxxx.
Instance Variables
defaultModel
execute
Execute the receiving action.
unload:
unloadClasses:
unloadPackage:
unregister:
unregisterPackageInfo:
unregisterRepositories:
unregisterWorkingCopy:
GoferUpdate
A GoferUpdate is xxxxxxxxx.
Instance Variables
addReference:
defaultModel
execute
Execute the receiving action.
referenceFor:
GoferVersionReference
A GoferVersionReference refers to a specific version of a Monticello package.
author
Answer the author of the receiver.
branch
Answer the branch of the receiver.
initializeName:
matches:
Answer true if the receiver matches aLoadableReference.
packageName
Answer the package of the receiver.
parseName:
versionNumber
Answer the version of the receiver.
GoferWorking
A GoferWorking is xxxxxxxxx.
Instance Variables
workingCopies: <Object>
workingCopies
- xxxxx
addReference:
initialize
Subclasses should redefine this method to perform initializations on instance creation
initializeOn:
workingCopies
Answer the working copies to be operated on.