A snappier Snapshotcello

I recently announced a little Pharo utility called Snapshotcello. While the announced version already solves a significant problem, I noticed while preparing the soon to be announced Moose 4.8 release, that there were still a couple of steps that required more automation. Namely, I wanted to be able to mark the new version as stable, commit the configuration, and ideally, to publish it to the official Pharo repository.

The newest version makes all these possible. Here is how I published the latest version of Snapshotcello itself:

Snapshotcello new
configurationClass: ConfigurationOfSnapshotcello;
sourceVersion: #development;
targetVersion: '1.4-snapshot';
snapshot;
makeStableFor: #'pharo2.x';
commit;
pushToPharo20Repository

First, you might noticed that the older API is slightly changed (publishVersion: is now replaced by an initial setter of the targetVersion: and a separate snapshot command). Besides that, here are the new commands:

  • makeStableFor: makes the #stable symbolic version point to the newly committed version for the given platform. In our case, I made it stable for pharo2.x.
  • commit commits the package of the configuration to the first non-local-cache Monticello repository associated with the package. Typically, this is the repository of the project, so in the case. In our example, the repository is the repository of Snapshotcello.
  • pushToPharo20Repository pushes the committed version to the official Pharo 2.0 repository.

The last command is particularly interesting because once you add this little command, you expose your package in every Pharo image. For example, in the picture below you can see Snapshotcello in the Pharo 2.0 configuration browser.

ConfigurationBrowser.png

Releasing a Pharo project has never been easier. Just give it a try for your beloved project. It takes only a couple of minutes.

Posted by Tudor Girba at 30 July 2013, 10:55 pm with tags pharo comment link

Snapshotcello: take a snapshot when you're ready

Metacello is a configuration management system that allows us to specify dependencies in Smalltalk projects systems. Like any similar system, the dependencies are defined at two levels:

  • dependencies between packages and sub-systems (captured in the so called baseline specifications), and
  • actual package and sub-system versions (specified in version specifications).

Having a configuration makes many things cheaper. Here are two: you can easily automate the image creation and blend it in a continuous integration job; and you can have nesting of projects. The second point is particularly interesting. For example, in the case of Moose, we have 32 nested projects.

One way to work with Metacello is to define your baseline, and for each commit to update the current development version. This can work well in small projects, but as soon as you go into larger projects with distributed teams that work on different schedules, it can be less appropriate. The greatest challenge comes from synchronization needs when versions are too fine grained: Because there is no merging support of configuration specifications, if the configuration changes too often (due to versions update), it can become a pain to handle the modifications. This can be solved with appropriate tooling, but at present time, it poses a significant problem in large projects.

In the case of Moose, we work in a distributed fashion, and the development philosophy that matches best is to work on the very latest of package versions and integrate aggressively all the time. To match this mode of development, we have introduced the rule that all baselines in Moose-projects only depend on #development versions of other the Moose-projects. Furthermore, the #development version always points to a baseline.

For example, ConfigurationOfMoose looks like:

development: spec
<symbolicVersion: #'development'>

spec for: #'pharo2.x' version: '4.8-baseline'.
baseline48: spec
<version: '4.8-baseline'>
spec for: #common do: [
...
spec project: 'Glamour' with: [
spec
className: 'ConfigurationOfGlamour';
file: 'ConfigurationOfGlamour';
version: #development;
repository: 'http://www.smalltalkhub.com/mc/Moose/Glamour/main' ].
...
]

In this way, when we load the #development version, we actually load the very latest of all projects. This works well when in development mode, but it is a pain at release time.

Theoretically, we would have to release all sub-projects at the same time and hard code all versions. Given that in Moose we have some 161 packages, it would be a very tedious job to do manually. We need a tool that provides some snapshotting capabilities.

Meet Snapshotcello, a little utility that Stéphane Ducasse and I worked on, and that enables you to freeze a snapshot of a given configuration based on what is already loaded in your current image.

The idea is simple. You develop against the latest versions of all packages, and commit your changes for each package. When you are ready for a release, you assemble your image, and construct a snapshot version that can be reloaded later.

As an example, suppose you want to take a snapshot of the current Moose baseline and publish it under 4.8-snapshot. The magic incantation goes like:

Snapshotcello new
configurationClass: ConfigurationOfMoose;
configurationVersion: #development;
publishVersion: '4.8-snapshot'

After a couple of seconds, the result looks like this:

version48snapshot: spec
"generated by Snapshotcello"
<version: '4.8-snapshot'>

spec for: #common do: [
self populateSpec: spec with: self snapshot1 ]
snapshot1
"generated by Snapshotcello"

^ #(
#('ConfigurationOfFame-TudorGirba.19.mcz'
'http://www.smalltalkhub.com/mc/Moose/Fame/main/'
'ConfigurationOfFame' )
...
#('Glamour-Announcements-TudorGirba.7.mcz'
'http://www.smalltalkhub.com/mc/Moose/Glamour/main/'
'Glamour-Announcements' )
...
)

The snapshot1 method lists all packages that should be loaded from all included projects in the right order. version48snapshot: provides a wrapper to make the code loadable through Metacello. Why not have the two in the same method? A technical limitation: we cannot have that many symbols in one Pharo method. To go around the problem, we create only one literal array with the data tuples and manipulate them through the populateSpec:with: utility method. The good news is that it works.

Snapshotcello is light. In fact, it comes with 2 classes of which one is an Error specialization. But, I think it opens doors to less constrained development. To give it a shot, you can load the code via:

Gofer new
smalltalkhubUser: 'girba' project: 'Snapshotcello';
package: 'ConfigurationOfSnapshotcello';
load.
(Smalltalk globals at: #ConfigurationOfSnapshotcello) loadDevelopment
Posted by Tudor Girba at 23 July 2013, 10:37 pm with tags pharo, moose comment link

Joining the Pharo Board

After five years of being involved in Pharo, mostly by developing Moose, I recently joined officially the Pharo Board. This is a responsibility I take seriously.

One of the points I will focus on, and likely stress everyone with, is Pharo marketing. I believe Pharo has reached the point at which marketing is crucial. It is already a sustainable and flourishing project mainly fueled by highly motivated and skilled innovators and some early adopters. The time has come to think about how to cross the famous chasm towards the majority of developers.

Marketing, like any other meaningful thing, requires design. Design requires feedback. And feedback requires time. That is why this endeavor is better started sooner rather than later.

And, yes, marketing can be meaningful, but only when we live what we sell. Pharo does offer a fantastic opportunity because when people talk about it, you can clearly see their eyes blinking. This reveals both value and values that are packaged deep in Pharo.

We just have to capitalize on that, and I want to start by making explicit what makes Pharo unique and valuable. We might think of various things, but we do not yet have a concerted message. This message, and I will aim at one single message, has to transpire in everything we do: from the way we design the code, to the concepts we adopt in the language, to the frameworks we build on top, to the developer and user experience, and to the stories we tell about Pharo.

This is exciting, but it requires team effort. This is where you come in. We want your energy outside of pure coding. Stories are particularly important, because at the end, this is what marketeers do. They sell through stories. If you are a Pharo contributor you are very likely a marketeer given that you just cannot stop talking about it. And demoing it. We look for Pharo stories that make your eyes blink. We want to know what you think is important to talk about.

More concrete proposals will come in the near future, but until then, please feel free to chip in your ideas.

Posted by Tudor Girba at 6 July 2013, 10:58 pm comment link

Demo-driven innovation - materials

On Friday, I led a one-day workshop on the topic of demo-driven innovation at the PhD Summer School organized at the University of Zurich. There were about 15 students in the audience. We had a relaxed and constructive time.

Talking about the process of innovation is not always perceived as a comfortable topic, but this time I enjoyed both the challenges and the answers that came from the students. It is always a privilege to be around eager young minds. I will follow up with more notes around raised issues such as whether six words can tell a story, or whether pure academic exercises can be considered to be innovation. In the meantime, the slides and handouts I used can be seen below.

Posted by Tudor Girba at 1 July 2013, 11:47 pm comment link