Versionner is for helping to automate writing the ConfigurationOf<PackageName> for a package or project, i.e. it assists you in creating Metacello configurations.
A Metacello configuration is a managed code package, which explicitly defines the dependencies between one package (perhaps your own package that you are developing) and other packages.
n.b. Groups in Metacello/Versionner are unrelated to groups in Nautilus/the System Browser.
MyKillerGame is a project with several loadable Pharo code packages:
- containing base classes with the domain model of your application
- a package providing own UI widgets for your application
- a package containing classes with the board of your killer game, ...
- a test package with SUnit tests that test classes in the MyKillerGame-Core package
- a test package with unit tests for MyKillerGame-UI-Widgets
- a test package with unit tests for MyKillerGame-UI-Board
So with this structure:
- the code is split into a domain model package and UI code package
- the test are separated from the code packages, which makes it easier to deploy the completed KillerGame out to end-users, later on. Having the tests in separate packages allows you to either load them for development or leave leave them unloaded in the production version
- you have a test package for each implementation package
Working through the Example with Versionner
- in Pharo 4 . left-click (i.e action-click) the Pharo desktop, World Menu | Tools | Versionner
- in Pharo 5 . ???
Versionner opens up a list of configurations in the image
(is that the meta-repository list of configurations that the image knows of? i.e. the one which is shown in the Configuration Browser?
is that the list of configurations which have already been loaded into the image?)
Two initial options:
"New project" - Create a new configuration for your project
"Load Project" - Load a configuration from a repository
and a third, greyed-out option
"Open project" (which can also be achieved by double-clicking on a package listed in the browser pane
Create the new project
Create a new configuration project "MyKillerGame", using "New project"
New project opens up a "Name of the new project" dialogue box, followed by an "Author identification" dialog, creates a development version of the project, and then brings up the main Versionner window
automatically defines a class ConfigurationOfMyKillerGame.
(This will hold all the Metacello load definitions),
automatically creates a package "ConfigurationOfMyKillerGame".
(This package is automatically placed in the "Configurations" group in the Packages pane of the Nautilus/System Browser).
Once the new project has been created, you can update the development version whenever you need to, using 'Save to Development'.
Define the package dependencies
The dependency browser shows you the dependencies of the already-loaded packages. If you reference a class in another package from within your project, it will be displayed in dependency browser
- add the necessary package
- add loading dependencies
the three packages of tests are each dependent on the package they test, because the test classes need the classes to test, so
- "MyKillerGame-Tests-Core" is dependent on the classes in "MyKillerGame-Core"
- MyKillerGame-Tests-UI-Widgets requires MyKillerGame-UI-Widgets
- MyKillerGame-Tests-UI-Board has a dependency on MyKillerGame-UI-Board
- MyKillerGame-UI-Board requires MyKillerGame-UI-Widgets
(as the game board requires fancy widgets )
- MyKillerGame-UI-Board requires MyKillerGame-Core
(as the game board requires the game's domain model/non UI logic)
Once these are defined, each and every package has all dependencies on any package that needs to be
loaded before the package itself works. And if every package within a project has all its dependencies defined, then the project as a whole has all its dependencies defined.
So we have one core package (with the game logic), two packages for UI related stuff, and three packages related to testing.
We can then group them in Versionner by adding Metacello Groups:
"Core" - containing the "MyKillerGame-Core" package
"UI" - containing the "MyKillerGame-UI-Board" and "MyKillerApp-UI-Widgets" packages
"Tests" - containing "MyKillerGame-Tests-Core", MyKillerGame-Tests-UI-Widgets" and "MyKillerGame-Tests-UI-Board"
This means that later you can load the "Core" group specifically, and Metacello will load just the packages listed in this group. Likewise, you could just load the "Tests" group. Metacello would then will load the packages in this group and the packages that they were defined as dependent on - their required packages.
There are two pseudo [Versionner?] groups
"all" - you define this, so it will load all packages related so your project.
"default" -> Monticello loads this group is by default
(i.e. if you do not give another group or package to load).
So in our example we can either
put all packages into the "all" group
put the group "Core","UI", "Tests" and tests into the [seems to be something missing here] group
(This is the easier and more logical approach of the two)
N.b. Groups can include packages and can also include other groups.
"all" should include all packages, as the name suggests. It's up to you how you define the "default".
For the MyKillerGame, the two best approaches are either
a) define "default" group to have group "all" (so by default anything is loaded for development)
b) define "default" group to have groups "Core" and "UI" (so by default anything is loaded for deployment, without tests)
Once the project repository is set up, you can directly commit the ConfigurationOf<PackageName> to the repository using "Commit the Project"?' There is no need to upload the changed "ConfigurationOfXXX " package using the Monticello browser. You can directly upload it into the repository from Versionner.
[Does this mean the package and project also do not need to be Monticello'd? That committing only the ConfigurationOf<PackageName> automagically stores the project and the packes within the project to their repositories?]
Beyond here lies Work-in-progress=========
Open some of the configuration classes in the browser and try to understand them.
Pharo 4: load from my ConfigurationBrowser
Pharo 5: load from the new CatalogBrowser that Esteban wrote. I polished it a little bit but
also extended Spotter to be able to load configurations from Catalog.
Example: In a fresh Pharo 5 image hit SHIFT + Enter (to open Spotter) and enter "DesktopMan", dependening on
network latency you quickly get "DesktopManager" project. If not wait a few seconds.
If you hit enter the project will be loaded. No need to open the Catalog Browser anymore. :simple_smile:
When the project is loaded just hit SHIFT+Enter again to open spotter and enter the class
name ConfigurationOfDesktopManager. Hit enter and Nautilus will open on the class
(the package is not selected by default but this is a known bug)
Check out the baseline defined in class ConfigurationOfDesktopManager.
Here we have two simple packages
"DesktopManager-Tests-Core" with the tests.
There is a dependency in the spec defined from "DesktopManager-Tests-Core" requiring "DesktopManager-Core" as the test package need the implementation package with the code to test.
There is also a group "Core" and a group "Tests".
The pseudo group "default" is defined to load the groups "Core" and "Tests".
The Baseline "0.1-baseline" defined in #baseline01: just defines depencies (=from which the load order is calculated by Metacello) and the groups.
Beside the Baseline there is also a real initial version "0.1.0" defined in #version010: method using this baseline and defining the appropriate versions of each package that fit together.
Semantic Versionning (http://semver.org/) is recommended - then you'd version you project with 0.1.0, 0.2.0, 0.3.0 etc, as you define milestones.
Some users of "MyKillerGame" might not be interested in a specific version. They just want to have a stable thing to work with.
Others might want to use the latest development version, which might well be unstable
This is what developer-defined symbolic versions like #stable or #baseline are for.
#development (usually references the latest baseline. This way, the latest version of each package is loaded in the right order).
Versionner - Commit Tool for Pharo (2/2)
Dependency Managment for Pharo
metacello-work - Metacello is a package management system for Smalltalk
define dependencies to other projects (for instance if you use JSON you might want to define a dependency to NeoJSON)
If the config is done right it will load NeoJSON first and then your code
versionner also allows to mark a combination of packages as "Version x.y.z"
Once the development version is complete, you can 'Release version'. Release versions are frozen - further changes to them are not allowed.