Skip to main content
Engineering LibreTexts

8.8: Groups

  • Page ID
    45265
  • \( \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}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    Suppose now that the CoolBrowser project grows: A developer writes some tests for CoolBrowser-Addons. These constitute a new package named CoolBrowser-AddonsTests, which naturally depends on CoolBrowser-Addons and CoolBrowser-Tests, as shown in Figure \(\PageIndex{1}\).

    A baseline with six groups.
    Figure \(\PageIndex{1}\): A baseline with six groups: default, Core, Extras, Tests, CompleteWithoutTests and CompleteWithTests.

    We may want to load projects with or without tests. In addition, it is convenient to be able to load all of the tests with a simple expression like:

    (ConfigurationOfCoolBrowser project version: '0.6') load: 'Tests'.
    

    instead of having to explicitly list all of the test packages, like this:

    (ConfigurationOfCoolBrowser project version: '0.6')
        load: #('CoolBrowser-Tests' 'CoolBrowser-AddonsTests').
    

    Metacello provides the notion of group. A group is a collection of items; each item may be a package, a project, or even another group.

    Groups are useful because they let you name sets of items for various purposes. Maybe you want to offer the user the possibility of installing just the core, or the core with add-ons and development features: you can make this easy be defining appropriate groups. Let’s go back to our example, and look at how we might define a new baseline, 0.6-baseline that defines 6 groups, as shown in Figure \(\PageIndex{1}\). In this example, we create a group called Tests that comprises CoolBrowser-Tests and CoolBrowser-AddonsTests.

    To define a group we use the method group: groupName with: groupElements. The with: argument can be a package name, a project, another group, or a collection of those things. Here is the code corresponding to Figure \(\PageIndex{1}\).

    ConfigurationOfCoolBrowser>>baseline06: spec
        <version: '0.6-baseline'>
        spec for: #common do: [
            spec blessing: #baseline.
            spec repository: 'http://www.example.com/CoolBrowser'.
            spec
                package: 'CoolBrowser-Core';
                package: 'CoolBrowser-Tests' with: [ spec requires: 'CoolBrowser-Core' ];
                package: 'CoolBrowser-Addons' with: [ spec requires: 'CoolBrowser-Core' ];
                package: 'CoolBrowser-AddonsTests' with: [
                    spec requires: #('CoolBrowser-Addons' 'CoolBrowser-Tests' ) ].
            spec
                group: ’default’ with: #(’CoolBrowser-Core’ ’CoolBrowser-Addons’);
                group: 'Core' with: #('CoolBrowser-Core');
                group: 'Extras' with: #('CoolBrowser-Addons');
                group: 'Tests' with: #('CoolBrowser-Tests' 'CoolBrowser-AddonsTests');
                group: 'CompleteWithoutTests' with: #('Core' 'Extras');
                group: 'CompleteWithTests' with: #('CompleteWithoutTests' 'Tests')
        ].
    

    Groups are defined in baselines. We are defining the groups in the baseline version, since a group is a structural component. Note that the default group will be used in the subsequent sections. Here the default group mentions that the two packages ’CoolBrowser-Core’ and ’CoolBrowser-Addons’ will be loaded when the method load is used.

    Using this baseline, we can now define version 0.6 to be the same as version 0.5, except for the addition of the new package CoolBrowser-AddonsTests.

    ConfigurationOfCoolBrowser>>version06: spec
        <version: ’0.6’ imports: #(’0.6-baseline’)>
    
        spec for: #common do: [
            spec
                package: 'CoolBrowser-Core' with: 'CoolBrowser-Core-BobJones.20';
                package: 'CoolBrowser-Tests' with: 'CoolBrowser-Tests-JohnLewis.8';
                package: 'CoolBrowser-Addons' with: 'CoolBrowser-Addons-JohnLewis.6';
                package: 'CoolBrowser-AddonsTests' with: 'CoolBrowser-AddonsTests-JohnLewis.1'].
    

    Examples. Once you have defined a group, you can use its name anywhere you would use the name of a project or package. The load: method takes as parameter the name of a package, a project, a group, or a collection of those items. All of the following statements are possible:

    (ConfigurationOfCoolBrowser project version: '0.6') load: 'CoolBrowser-Core'.
        "Load a single package"
    
    (ConfigurationOfCoolBrowser project version: '0.6') load: 'Core'.
        "Load a single group"
    
    (ConfigurationOfCoolBrowser project version: '0.6') load: 'CompleteWithTests'.
        "Load a single group"
    
    (ConfigurationOfCoolBrowser project version: '0.6')
        load: #('CoolBrowser-Core' 'Tests').
        "Loads a package and a group"
    
    (ConfigurationOfCoolBrowser project version: '0.6')
        load: #('CoolBrowser-Core' 'CoolBrowser-Addons' 'Tests').
        "Loads two packages and a group"
    
    (ConfigurationOfCoolBrowser project version: '0.6')
        load: #('CoolBrowser-Core' 'CoolBrowser-Tests').
        "Loads two packages"
    
    (ConfigurationOfCoolBrowser project version: '0.6') load: #('Core' 'Tests').
        "Loads two groups"
    

    The groups default and 'ALL'. The default group is a special one. The load message loads the members of the default group while loading the ALL group will load all the packages. Moreover, by default, default loads ALL!

    (ConfigurationOfCoolBrowser project version: '0.6') load.
    

    loads just CoolBrowser-Core and CoolBrowser-Addons.

    In the presence of a default group, how do you load all the packages of a project? You use the predefined ALL group, as shown below:

    (ConfigurationOfCoolBrowser project version: '0.6') load: 'ALL'.
    

    About Core, Tests and default

    We often get at least two groups in a configuration: Core (the real code) and Tests (the associated tests). The question is what should be loaded by the default group (remember, this is what gets loaded when you do not specify anything as a parameter).

    By saying spec group: 'default' with: #('Core') we say that by default we do not load tests.

    Now if we do not specify any default, it will take everything by default, hence it will be equivalent in our case with spec group: 'default' with: #('Core' ' Tests')

    We believe that by using default it is good to load the tests as well. This is why, either we explicitly put the Tests group in the default group, or we do not specify a default at all.


    This page titled 8.8: Groups is shared under a CC BY-SA 3.0 license and was authored, remixed, and/or curated by Alexandre Bergel, Damien Cassou, Stéphane Ducasse, Jannik Laval (Square Bracket Associates) via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.