I have a seaside project that will be installed in a typical fashion headless 
on a server somewhere on the net. The project is in its final stage so I 
started to care about the size of the image. Or better: The size of the image 
is not my main concern but the number of packages installed. The less packages 
you load the better it is, it is that simple. 
This time I encountered a problem that I often see but this particular one 
explains in a very good way that how we use metacello can be improved.

In my project I load only Seaside-Core. This has the advantage of loading far 
less packages and I don't have the need to remove a bunch of registered web 
applications that registered themselves when being loaded. 
I make use of a bootstrap template bought somewhere on the net. I use magritte 
a lot so I was happy to see that there is a package called BootstrapMagritte. 
The package extends some magritte ui classes and overwrites some methods to add 
specific classes to HTML tags. Basically not very much code. 
What happended after I added the package as a dependency to my own project you 
can see here in the load directive of metacello

linear load : 
        explicit load : 0.2.3 [ConfigurationOfBootstrapMagritte]
        linear load : 0.2.3 [ConfigurationOfBootstrapMagritte]
                linear load : 3.5.0 [ConfigurationOfMagritte3]
                        linear load : 1.1.0 
[ConfigurationOfMagritteGlamourForPharo40]
                                load : 
Glamour-Presentations.issue_1126-SeanDeNigris.178
                                load : 
Glamour-Morphic-Renderer.issue_1126-SeanDeNigris.325
                        explicit load : 3.1.5 [ConfigurationOfSeaside3]
                        linear load : 3.1.5 [ConfigurationOfSeaside3]
                                explicit load : 0.26 [ConfigurationOfParasol]
                                linear load : 0.26 [ConfigurationOfParasol]
                                        linear load : 3.2.0 
[ConfigurationOfSeaside3]
                                load : 
Seaside-Tests-REST-Core-EstebanMaringolo.34

This is wrong in so many ways. I load a little extensions to my web application 
and end up loading _all_ of seaside which loads beach parasol (a ui testing 
framework), _all_ of magritte which in turn loads glamour packages (a ui 
toolkit). So at this point I think WTF?

Why does this happen? Because the "default" group in many projects contains all 
of the packages and dependencies of the project. I thought at first this is 
wrong but in the meantime I think it is right. Whenever a configuration is 
loaded without additional parameters the "default" group gets loaded. This is 
the best scenario for newcomers (e.g. using the catalog to load). They don't 
know better but want to see what the package has to offer. Fine, we should 
support that. 

For managing projects this gets annoying really quick like you can see above. 
It would always load all dependencies and all packages of every project that 
your own project depends. This is a no-go. To circumvent this a lot of people 
add a "core" group to their configurations (loading the essential parts). This 
is great because in my own project I can add a dependency to a project and load 
only the "core" group. This works if the dependency chain is not very long (at 
best it works in depth 1 ;) ). As soon as a project has two interesting groups 
the problem gets worse. A good example is magritte. It is useful for describing 
your model as well as it contains useful seaside components. The moment I add a 
dependency from my model package to magritte seaside I know it is wrong. I find 
myself sometimes duplicating dependencies just to mitigate the effect. I do 
something like

                        project: 'Magritte3Seaside' with: [
                                spec
                                        className: #ConfigurationOfMagritte3;
                                        versionString: #'stable';
                                        loads: #('Seaside' );
                                        repository: 
'http://smalltalkhub.com/mc/Magritte/Magritte3/main/' ];
                        project: 'Magritte3Core' with: [
                                spec
                                        className: #ConfigurationOfMagritte3;
                                        versionString: #'stable';
                                        loads: #('Core' );
                                        repository: 
'http://smalltalkhub.com/mc/Magritte/Magritte3/main/' ];

and…
                        package: #'MyProject-Model-Core' with: [
                                spec requires: #( 'Magritte3Core' ). ];
                        package: #'MyProject-UI-Core' with: [
                                spec requires: #( 'Seaside3' 'Magritte3Seaside' 
'BootstrapMagritte'  ). ];


just to be able to put the right dependencies. But this way is cumbersome to do 
and not support by tools like Versionner. 

The main problem to me is that the maintainer of the configuration defines the 
granularity of pieces to load forcing me to do stupid workarounds to achieve 
what I want. To me the problem is that the separation is not done properly. I 
think the logic of having loads() in the baseline and a pure string like 
"Magritte3Core" in the dependency spec is reversed. It should be

                        project: 'Magritte3' with: [
                                spec
                                        className: #ConfigurationOfMagritte3;
                                        versionString: #'stable';
                                        repository: 
'http://smalltalkhub.com/mc/Magritte/Magritte3/main/' ];

and…

                        package: #'MyProject-Model-Core' with: [
                                spec requires: #( 'Magritte3:Core' ). ];
                        package: #'MyProject-UI-Core' with: [
                                spec requires: #( 'Seaside3' 
'Magritte3:Seaside' 'BootstrapMagritte'  ). ];

Note the "Magritte3:Core" in the dependency spec. The meaning is that there is 
a dependency to Magritte3 and group Core. This way dependencies can be properly 
aligned. Or are there other way to deal with it?

What do you think?

Norbert

Reply via email to