Skip to main content
Engineering LibreTexts

6.3: Monticello

  • Page ID
    36362
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)

    We gave you a quick overview of Monticello, Squeak’s packaging tool, in Section 2.9. However, Monticello has many more features than were discussed there. Because Monticello manages Packages, before telling you more about Monticello, it’s important that we first explain exactly what a package is.

    Packages: declarative categorization of Squeak code

    The package system is a simple, lightweight way of organizing Smalltalk source code. It leverages the long-used naming convention mentioned above (Section 6.2), but adds to it in an important way.

    Let’s explain this using an example. Suppose that you are developing a framework named to facilitate the use of relational databases from Squeak. You have decided to call your framework SqueakLink, and have created a series of system categories to contain all of the classes that you have written, e.g.,

    • Category 'SqueakLink-Connections' contains OracleConnection MySQLConnection PostgresConnection
    • Category 'SqueakLink-Model' contains DBTable DBRow DBQuery

    and so on. However, not all of your code will reside in these classes. For example, you may also have a series of methods to convert objects into an SQL-friendly format:

    Object»asSQL
    String»asSQL
    Date»asSQL
    

    These methods belong in the same package as the classes in the categories SqueakLink-Connections and SqueakLink-Model. But clearly the whole of class Object does not belong in your package! So you need a way of putting certain methods in a package, even though the rest of the class is in another package.

    The way that you do this is by placing those methods in a protocol (of Object, String, Date, and so on) named *squeaklink (note the initial asterisk, and the lower-case name). The combination of the SqueakLink-... categories and the *squeaklink protocols form a package named SqueakLink. To be precise, the rules for what goes in a package are as follows.

    A package named Foo contains:

    1. all class definitions of classes in the category Foo, or in categories with names starting with Foo-, and
    2. all method definitions in any class in a protocol named *foo or whose name starts with *foo- (when performing this name comparison, the case of the letters in the names is ignored), and
    3. all methods in classes in the category Foo, or in a category whose name starts with Foo-, except for those methods in protocols whose names start with *.

    A consequence of these rules is that each class definition and each method belongs to exactly one package. The except in the last rule has to be there because those methods must belong to other packages. The reason for ignoring case in rule 2 is that, by convention, protocol names are all lower case (and may include spaces), while category names use CamelCase (and don’t include spaces).

    The class PackageInfo implements these rules, and one way to get a feel for them is to experiment with this class.

    \(\bigstar\) Try this in your image, which should contain the classes PackageInfo and RefactoringBrowser.

    The Refactoring Browser code uses these package naming conventions, with RefactoringEngine as the package name. In a workspace, create a model of this package with

    refactory := PackageInfo named: 'RefactoringEngine'.
    

    It is now possible to introspect on this package. For example, refactory classes will return the long list of classes that make up the Refactoring Engine and the Refactoring Browser. refactory coreMethods will return a list of MethodReferences for all of the methods in those classes. refactory extensionMethods is perhaps one of the most interesting queries: it will return a list of all methods contained in the RefactoringEngine package but not contained within a RefactoringEngine class. This includes, for example, ClassDescription»chooseThisClassInstVarThenDo: and SharedPool class»keys.

    Packages are a relatively new addition to Squeak, but since the package naming conventions were based on those already in use, it is possible to use PackageInfo to analyze older code that has not been explicitly adapted to work with it.

    \(\bigstar\) Evaluate (PackageInfo named: 'Collections') externalSubclasses; this expression will answer a list of all subclasses of Collection that are not in the Collections package.

    You can send fileOut to an instance of PackageInfo to get a change set of the entire package. For more sophisticated versioning of packages, we use Monticello.

    Basic Monticello

    Monticello is named after the mountaintop home of Thomas Jefferson, third president of the United States and author of the Statute of Virginia for Religious Freedom. The name means “little mountain” in Italian, and so it is always pronounced with an Italian “c”, which sounds like the “ch” in chair: Mont-y’-che-llo.

    The Monticello browser.
    Figure \(\PageIndex{1}\): The Monticello browser.

    When you open the Monticello browser, you will see two list panes and a row of buttons, as shown in Figure \(\PageIndex{1}\). The left-hand pane lists all of the packages that have been loaded into the image that you are running; the particular version of the package is shown in parentheses after the name.

    The right-hand pane lists all of the source-code repositories that Monticello knows about, usually because it has loaded code from them. If you select a package in the left pane, the right pane is filtered to show only those repositories that contain versions of the selected package.

    One of the repositories is a directory named package-cache, which is a sub-directory of the directory in which your image is running. When you load code from or write code to a remote repository, a copy is also saved in the package cache. This can be useful if the network is not available and you need to access a package. Also, if you are given a Monticello (.mcz) file directly, for example as an email attachment, the most convenient way to access it is to place it in the package-cache directory.

    To add a new repository to the list, click the +Repository, and choose the kind of repository from the pop-up menu. Let’s add an HTTP repository.

    \(\bigstar\) Open Monticello, click on +Repository, and select HTTP. Edit the dialog to read:

    MCHttpRepository
        location: 'http://squeaksource.com/SqueakByExample'
        user: ''
        password: ''
    

    Then click on Open to open a repository browser on this repository. You should see something like Figure \(\PageIndex{2}\). On the left is a list of all of the packages in the repository; if you select one, then the pane on the right will show all of the versions of the selected package in this repository.

    A Repository browser.
    Figure \(\PageIndex{2}\): A Repository browser.

    If you select one of the versions, you can Browse it (without loading it into your image), Load it, or look at the Changes that will be made to your image by loading the selected version. You can also make a Copy of a version of a package, which you can then write to another repository.

    As you can see, the names of versions contain the name of the package, the initials of the author of the version, and a version number. The version name is also the name of the file in the repository. Never change these names; correct operation of Monticello depends on them! Monticello version files are just zip archives, and if you are curious you can unpack them with a zip tool, but the best way to look at their contents is using Monticello itself.

    To create a package with Monticello, you have to do two things: write some code, and tell Monticello about it.

    \(\bigstar\) Create a category called SBE-Monticello, and put a couple of classes in it, as shown in Figure \(\PageIndex{3}\). Also, create a method in an existing class, and put it in the same package as your classes, using the rules from above — see Figure \(\PageIndex{4}\).

    Two classes in the “SBE” package.
    Figure \(\PageIndex{3}\): Two classes in the “SBE” package.

    To tell Monticello about your package, click on +Package, and type the name of the package, in this case “SBE”. Monticello will add SBE to its list of packages; the package entry will be marked with an asterisk to show that the version in the image has not yet been written to any repository.

    Initially, the only repository associated with this package will be your package cache, as shown in Figure \(\PageIndex{5}\). That’s OK: you can still save the code, which will cause it to be written to the package cache. Just click Save and you will be invited to provide a log message for the version of the package that you are about to save, as shown in Figure \(\PageIndex{6}\); when you accept the message, Monticello will save your package. To indicate this, the asterisk decorating the name in Monticello’s package pane will be removed, and the version number added.

    If you then make a change to the package — say by adding a method to one of the classes — the asterisk will re-appear, showing that you have unsaved changes. If you open a repository browser on the package cache, you can select the saved version, and use Changes and the other buttons. You can of course save the new version to the repository too; once you Refresh the repository view, it should look like Figure \(\PageIndex{7}\).

    To save the new package to a repository other than the package cache, you need to first make sure that Monticello knows about the repository, adding it if necessary. Then you can use the Copy in the package-cache repository browser, and select the repository to which the package should be copied. You can also associate the desired repository with the package by using the yellow button menu item add to package... on the repository, as shown in Figure \(\PageIndex{8}\). Once the package knows about a repository, you can save a new version by selecting the repository and the package in the Monticello Browser, and clicking Save. Of course, you must have permission to write to a repository. The SqueakByExample repository on SqueakSource is world readable but not world writable, so if you try and save there, you will see an error message. However, you can create your own repository on SqueakSource by using the web interface at http://www.squeaksource.com, and use this to save your work. This is especially useful as a mechanism to share your code with friends, or if you use multiple computers.

    If you do try and save to a repository where you don’t have write permission, a version will nevertheless be written to the package-cache.

    An extension method that will also be in the “SBE” package.
    Figure \(\PageIndex{4}\): An extension method that will also be in the “SBE” package.
    The as-yet-unsaved SBE package in Monticello.
    Figure \(\PageIndex{5}\): The as-yet-unsaved SBE package in Monticello.
    Providing a log message for a new version of a package.
    Figure \(\PageIndex{6}\): Providing a log message for a new version of a package.
    Two versions of our package are now in the package cache.
    Figure \(\PageIndex{7}\): Two versions of our package are now in the package cache.
    Adding a repository to the set of repositories associated with a package.
    Figure \(\PageIndex{8}\): Adding a repository to the set of repositories associated with a package.

    So you can recover by editing the repository information (yellow button menu in the Monticello Browser) or choosing a different repository, and then using Copy from the package-cache browser.


    This page titled 6.3: Monticello is shared under a CC BY-SA 3.0 license and was authored, remixed, and/or curated by Andrew P. Black, Stéphane Ducasse, Oscar Nierstrasz, Damien Pollet via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.