Squeak
  links to this page:    
View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
Make a compact model of your package ecosystem
Last updated at 12:41 pm UTC on 5 May 2017

A new, orthogonal subclass hierarchy

The subclasses of Installer have traditionally been to vary the technical implementation of interfacing to the many various packaging systems that have been developed by the community. Now, a new subclass hierarchy is emerging which leverages configuration with Monticello, Squeak's defacto SCM tool which began about 2005.

A terse representation

The idea is to provide the user a way to essentially just list the load order of packages as a Smalltalk Array literal, and the symbolic name of the repository and project directory they reside at. For example, Installer>>#ffi is:
ffi
	"Foreign Function Interface."
	^ { #squeak -> 'FFI'.
	'FFI-Pools'.
	'FFI-Kernel' }

The first line specifies the repository and project directory where the package names that follow can be found. Browse implementors of #squeak to see that it refers to the Repository at 'source.squeak.org'.

Now, take a look at Installer>>#ffiTests.
ffiTests
	"Tests for Foreign Function Interface."
	^ { self ffi.
	#squeak -> 'FFI'.
	'FFI-Tests' }

ffiTests requires ffi, of course. Note the first line. It continues the flat-list metaphor and very easy for the user to write and understand, but evaluating to an inner Array specification as the first element. The system employs a recursive depth-first enumeration on this to satisfy many configuration use cases.

(Note: In ffiTests, above, its recommended to always specify the repository immediately preceding the package names, even though we know they're the same as #ffi, we don't want to count on that).

Loading code

The most basic use case is merging entire suites of packages, without disrupting any changes to existing packages even if they should be part of the new load. For example, if first you executed:
  Installer new merge: #ffi

And then made some local changes to FFI, wanted to see if anything broke, so load #ffiTests. Further, pretend someone else had made a new version of FFI, then executing:
  Installer new merge: #ffiTests

would merge the new version without disturbing local changes when it loaded ffiTests.

Integrating local work on remote packages

When working on improving code in packages, it is often desirable to work with them from one's own local repositories. The symbolic repostiory specifications can be overridden like:
  Installer
    overrideRepository: #squeak
    with: #local

Project-specific overrides are also supported:
  Installer
    overrideRepository: #squeak->'FFI'
    with: #local


#local refers to the repository defined by Installer class>>#localRepository, which defaults to a directory named 'mc' in the working directory, which can be overridden if necessary.

The overrides may either be symbolic or the actual MCRepository instances.

Automatic Repository configuration

When merging #ffi, above, the repository's they were loaded from are added automatically to each package loaded. Whether wanting to save changes from local to remote, or loaded remote and want to save local changes, it is useful to be able to easily add the other.
  MyInstaller addLocalRepositories.
  MyInstaller addRemoteRepositories.


Publish latest local versions

Every once in a while, its nice to publish the latest version of each package to their various repositories. This can be done like this:
  MyInstaller new
    copyLocalVersionsToRemoteFor: #myPackage
    id: idString
    password: pwString


It does not make any new Versions, it only copies the latest existing Version of each package to its remote repository defined in its package-definitions method.

Seamless Partition between proprietary and public code

I have my own personal subhierarchy of Installer.
  Installer
    MaInstaller
      MaCommercialInstaller
        HaeInstaller
        MyInstaller

Each defines its own method category, 'package-definitions', which is a special category where the package lists are put:.
InstallerBase Squeak packages #(connectors curvedSpaceExplorer ffi ffiTests htmlValidator jsonParser maInstalller mathMorphs...)
MaInstallerMy public open-source projects #(base serializer clientServer magmaClient magmaServer maUi)
MaCommercialInstallerMy proprietary closed-source projects #(geoSupport geoNamesCore geoNamesMaui kmlCore kmlMaui tephraCore tephraMaui)
HaeInstallerClient-specific package-definitions.
MyInstallerMy personal projects which are not shared.

How-To

By creating your own subclass of Installer which organize your own public and proprietary packages, you too can enjoy the major configuration conveniences afforded by this simple, terse representation. It is not intended to replace any other system like Metacello, Git, SqueakMap or anything. It is just a cheap and terse way to model one's packages which provides easy access and manipulation that support configuration use-cases.