[squeak-dev] Package commit granularity vs. Project commit granularity (was: FileStreams Limit)

Jörg Belger unique75 at web.de
Mon Feb 21 14:25:10 UTC 2022


Hi Bernhard,

If I follow your suggestions and of course if I understand it correctly, I would do the following:

	- create package „Seaside-Implementation“
	- create package „Seaside-Tests“
	- create configuration „Seaside-Config“ that loads the both packages

This sounds to me what we have now in Monticello, except maybe that I do not need to execute some magic workspace code anymore. But what is when I then do the following:

	- create package „MyApp-Implementation“
	- create package „MyApp-Tests“
	- create configuration „MyApp-Config“

But my app needs „Seaside“ as prerequisite. As there are no dependencies between configurations, I cannot use „Seaside-Config“ as prerequisite in „MypApp-Config“. I need to add all Seaside-Packages manually to my special „MyApp-Config“. This is not what I would call „thinking in modules“. 

A bundle in Store cannot contain code. Only a package can have code. You can build hierarchical structures with bundles, like this (B=Bundle, P=Package):

	B: MyApp-All
		B: MyApp-Prerequisites
			B: Seaside
				P: Seaside-Implementation
				P: Seaside-Tests
		B: MyApp
			P: MyApp-Implementation
			P: MyApp-Tests

The hierarchical structure is visible in the refactoring browser and can be graphically edited. Assume the „P: MyApp-Implementation“ contains Seaside-code, then you need „B: Seaside“ as prerequisite. If you set this prerequisite you can load „P: MyApp-Implementation“ as single package without loading errors. But of course you can also set the prerequisite one level higher in „B: MyApp“ if you don’t want to specify it on package level. But then you need to load „B: MyApp“, because the single packages has not the right dependencies set. Normally you set the dependencies on package level so that each is well defined and dependencies are set. The same is for „P: MyApp-Tests“. Normally you set „P: MyApp-Implementation“ as prerequisite, so that you can simply load „P: MyApp-Tests“ and the base of MyApp is loaded too. The bundles are often used as container to form bigger modules, so that I can load these to have more loaded.

The super bundle „B: MyApp-All“ includes your app and all your needed prerequisites in one snapshot, where all versions fixed/hardlinked. If you publish „B: MyApp-All“ then all including bundles/packages are published with their current version that you have loaded in image. That means you fix the current Seaside-Version along with your current App-Version. But nobody prevents you from to publish „B: MyApp“ alone with a new version.

In this way you build more and more modules, that are fully loadable. I think you can also create an empty bundle that has only prerequisites set, which matches most of your description about configurations, but normally the bundle is used to group things together to bigger modules.

Jörg

> Am 21.02.2022 um 09:25 schrieb Bernhard Pieber <bernhard at pieber.com>:
> 
> Hi Jörg,
> 
> Maybe I misunderstood how bundles work. Can a bundle contain code (classes and methods) which does not belong to the contained packages itself? If the answer is yes, I misunderstood. If the answer is no, this is what I meant: a bundle is an artefact which is used to specify dependencies but it is a not a package itself (i.e. containing code) but a separate artefact.
> 
> Regarding prerequisites between bundles/ConfigurationMaps: I used ENVY in several large scale projects. For the first few years we used fine grained ConfigurationMaps with prerequisites between them, e.g. Model, Server, Client/UI, Tests, Tools etc. The goals was that each package should be in just one ConfigurationMap. It lead to a lot of complexity and extra work and still there always were problems. Then we switched to few flat ConfigurationMaps without prerequisites, e.g. Server, Client, Dev. The goal now was to have just one configuration map per deployment. It was much less work and much simpler.
> 
> So I have come to the conclusion that the simplest possible solution for version and configuration management would be the following:
> - Packages containing code which can be versioned.
> - Configurations wich specify which package versions work together (and in which order they have to be loaded) and can be versioned as well.
> 
> In other words: To simplify I would remove the possibility to specify prerequisites on package level, and I would remove the possibility to specify dependencies between configurations. There needs to be tooling to import package versions from one configuration to another and to update configurations with the latest package versions for this to be convenient, though.
> 
> To me it seems that the transitive dependencies between Metacello configurations/baselines account for most of the problems with its use. Don’t get me wrong: Metacello has served the wider Smalltalk community very well. It had high ambition (dialect independence) which it achieved. It is very complex, though. The switch from ConfigurationOfXXX (Monticello) and BaselineOfXXX (Git) is so significant, that it should have been a separate tool IMHO. For GemStone, there is a new tool in the works called Rowan that will replace Metacello IIUC.
> 
> The current solution (method versions/changes file, Monticello, Monticello configurations, Metacello, Git, Squot) is much too complex for my taste. What other than the simplest possible version and configuration management solution can be the right one for Smalltalk? ;-) Alas, this is only a dream because it is way too much work to be implemented with the resources of our small community.
> 
> Cheers,
> Bernhard
> 
>> Am 20.02.2022 um 18:19 schrieb Jörg Belger <unique75 at web.de <mailto:unique75 at web.de>>:
>> 
>> Hi Bernhard,
>> 
>> Option 2 sounds for me too complicated :-)
>> 
>> Store has simply „bundles“ and „packages“. Both are first-class objects, both can have prerequisites, both can be prerequisites, both share the same superclass and are almost equal. The only difference is that a bundle is more like a container for other bundles/packages, whereas a package is more like a leaf-item that contains code. The class browser of Squeak shows you a flat list of class categories, but the refactoring browser in Visualworks shows you a hierarchical tree of bundles/packages.
>> 
>> There is no need for all the overcomplicated stuff like ConfigurationsOf, extra Maps and Outside-Dependency-Things etc.
>> Just create a package or bundle and set prerequisites into each of them. If you want to fix/hardlink multiple packages/bundles with their versions together, just put a bundle around and version that surrounding bundle. That’s all.
>> 
>> Jörg
>> 
>>> Am 20.02.2022 um 16:33 schrieb Bernhard Pieber <bernhard at pieber.com <mailto:bernhard at pieber.com>>:
>>> 
>>> Hi Jörg,
>>> 
>>> Thanks for the detailed description about how Store works. In fact, it reminds me very much of ENVY. What you describe as a bundle is called ConfigurationMap in ENVY, which I think is quite a fitting name. Packages are called Applications and SubApplications, which are very bad names. In addition there are ConfigurationExpressions which are useful for conditional loading on different platforms and dialects.
>>> 
>>> I agree that this system works very well. Bundles/ConfigurationMaps are essential in addition to packages IMO. As far as I understand it, Git completely misses this functionality. This is intentional, as Git is just a versioning system not a configuration management system. That means you need additional tools to solve that problem.
>>> 
>>> For dependency management there are two possible solutions:
>>> a) Each package specifies (stores) the dependencies it needs, either a specific version or a range of versions or just the name of packages.
>>> b) The dependencies between the packages are specified (stored) outside the package itself in separate artefacts, which itself need to be versioned, i.e. bundles/ConfigurationMaps/configurations.
>>> 
>>> I think it is confusing to mix both approaches and according to my experience the second approach is much better. The first approach is used far more often, though. Monticello dependencies and Metacello are examples.
>>> 
>>> Monticello configurations on the other hand are exactly the same thing as bundles/ConfigurationMaps IMO. The tooling is not good enough, which I think is one the reasons why it is not used more often.
>>> 
>>> But I think you should be able to achieve the working style you described with Monticello and Monticello configurations.
>>> 
>>> Cheers,
>>> Bernhard
>>> 
>>> 
>>>> Am 19.02.2022 um 19:49 schrieb Jörg Belger <unique75 at web.de <mailto:unique75 at web.de>>:
>>>> 
>>>> Ohh yes, you are right Jacob, I sent it only to you, it was a mistake. So I will send it now to the mailing list, maybe others find it also interesting. I hope it, I don’t want to be punished for my clear announcements :-)
>>>> 
>>>> I can imagine that we could also create issues on Github for ideas/proposals/wishes what the most important things are to do. The people can then discuss and prioritize them there and the discussion is then preserved and well documented for future. Everyone who feels called can then pick up such „proposal issues“ and just try to implement it. But discussion these things via email is bad, because all the discussion is forgotten in 1 month and nobody searches in its emails for such things. What we need is a notification system in Github, everybody who wants to be informed by email can do it. I guess Github have something like this, but I am not sure. It would be funny if the master of versioning systems have not such a feature, where people can add itself for notifications. Maybe this here is read by a Github expert, I am just a newbie in Github.
>>>> 
>>>> Jörg
>>>> 
>>>>> Am 19.02.2022 um 17:26 schrieb Jakob Reschke <jakres+squeak at gmail.com <mailto:jakres+squeak at gmail.com>>:
>>>>> 
>>>>> Hi Jörg,
>>>>> 
>>>>> Thank you for this practical explanation! Did you intentionally send
>>>>> it only to me and not to the list?
>>>>> 
>>>>> Kind regards,
>>>>> Jakob
>>>>> 
>>>>> Am Sa., 19. Feb. 2022 um 14:05 Uhr schrieb Jörg Belger <unique75 at web.de <mailto:unique75 at web.de>>:
>>>>>> 
>>>>>> Hi Jacob,
>>>>>> 
>>>>>> Please let me give an insight how my workflow is in business with Cincom VisualWorks + Store and why I have the feeling that the Squeak versioning with Monticello and Github is over-complicated and user-unfriendly.
>>>>>> 
>>>>>> Store breaks the world into bundles and packages. A bundle can contain other bundles and packages, whereas a package contains code. You can have of course multiple repositories, but only one active repository, where all your publishes/commits goes into. Store is fully integrated into class browser and you see there the bundles/packages as first.class-objects and can right click it and publish it to the active connected repository. You can also add class extension methods into a package, so that you have a view on all your methods that you added to system classes.
>>>>>> 
>>>>>> Let´s assume I create now a new package P1, put some code inside and publish it as V1.0. I create now a second package P2 and publish it as V1.0. Let’s assume I did more changes and currently I have already „package P1 V1.2“ and „package P2 V2.7“ in image and repository. I can now create a bundle B, add the two packages P1 and P2 to it and publish the bundle as V1.0. Meanwhile another person works on „package P1“ und publishes V1.3. Every time you load now „bundle B V1.0“ you will get the „package P1 V1.2“ and „package P2 V2.7“ in image. The changes of „package P1 V1.3“ does not matter, because you have fixed/linked some specific package versions into bundle version V1.0. We do that often to combine some tested versions of different subprojects together. From time to time somebody goes through the bundle and look for newer package versions and create a new tested release, where all the new package versions are fixed/linked together again and which is tested. The bundle B is then published as V1.1.
>>>>>> 
>>>>>> You can also set „package P1“ as prerequisite for „package P2“. Every time you load P2 you will get a dialog to select the right version of P1. Prerequisite loading is only done within the same active repository. Depending on settings a prerequisite can also be loaded from the installation path as a parcel. But there is no way to load prerequisites from other repositories than the active one.
>>>>>> 
>>>>>> Let´s assume we allow multi-repository prerequisites. The Core team adds „package P2“ to its supported things, because it is a wonderful tool and put it into the Core repository R2. But this package P2 depends on package P1 which is on repository R1. The repository R1 is maintained by one private person and 1 year later the repository is deleted or moved to another location or the package P1 there is broken and unloadable etc. etc. etc. There are many reason for that, e.g. the one person has another working style, another quality assumptions etc.
>>>>>> 
>>>>>> What is the end of this story? You have a package P2 on the Core repository R2, which is supported… but it does not work, coz side dependencies are out of control and does not work anymore. This is exactly the situation where I run often into when I tried to load things. The URLs in the configuration of supported things does not work anymore or the version did not match anymore, I got always loading hell problems and that is just frustrating. You want to load something and everything you try is not working.
>>>>>> 
>>>>>> I do not a see a good way to work with Github like I do it with Store, where I can independently publish different packages with different versions, have prerequisites or fix/link bundle versions. And I think it is not the right way to create a Github repository for every single package. A package is only a logic unit to divide something in logical pieces, it is not a full project or a full eco system like Squeak. I think Monticello is the one that looks to me similar to Store. But it needs a better prerequisite system and not the messy configurations. When I browse a repository version that browser looks to me that this should be the class browser, because I see there my package structure and all the extensions methods.
>>>>>> 
>>>>>> Surely I am a newbie to Monticello and all I learned so far is that I load a „ConfigurationOfXXX“ from repository, but then all I know is to execute some workspace code like „ConfigurationOfXXX project latestVersion load“. Maybe there is a better way to not enter always the workspace code. I want simply to load a package with a one-click action in a repository browser and I do not want to think about not-working side-reference URLs and other things. Often I searched around the internet to find a working version of some specific prerequisite and it is always a mess. There happened so crazy things, that I wanted to load something that depends on FFI, but the FFI that is loaded through the Configuration is outdated. I find then a newer FFI in the internet, load that before and the other package was working better. This is nothing what a newbie wants to have when you just evaluate the new Squeak world.
>>>>>> 
>>>>>> One other topic I want to mention about versioning is… if we have an issue tracking system… we normally publish a bundle/package with that issue number inside the version string. That means somebody finds a bug and creates an issue 4711 and put it into the public pool. Another person can pickup this issue 4711, solve the problem and publish the changes as „package P1 V1.1 + issue 4711 1“. The last number „1“ is incremented with every publish. This is very helpful, because others see immediately that this version branch is forbidden and „work in progress“. When the issue is finished it is delegated to a reviewer or a pool, where others can pick it up and make the review. The reviewer loads the „issue 4711“ branch of the package, integrate it and publish a new trunk version of the package, in that case it would be „package P1 V1.2“. The advantage is that every time you asking yourself why a specific change was coming into a method, you can see that „issue 4711“ branch in the version history and then you can look into the issue tracker at issue 4711 what the reasons were.
>>>>>> 
>>>>>> I do not see how we can work in such a professional way together when we are using emails. I am seeing often emails flying around with Review requests, but emails can be forgotten. The packages contain only some magic name, but no issue number, so the changes are not traceable from what issue they came and why and when. And please guess me, it happens often that you ask 2 years later why a specific change is inside. It is very helpful then to have the documentation history in the issue what the person thought 2 years before.
>>>>>> 
>>>>>> I think the optimal solution would be if everybody can subscribe in Github for specific „labels“, „projects“ or whatever. Then everybody can decide by yourself if he/she wants email notification or not. But I do not know if Github can do this.
>>>>>> 
>>>>>> Jörg
>>>>>> 
>>>>>> 
>>>>>>> Am 19.02.2022 um 12:07 schrieb Jakob Reschke <jakres+squeak at gmail.com <mailto:jakres+squeak at gmail.com>>:
>>>>>>> 
>>>>>>> Dear Jörg, dear all,
>>>>>>> 
>>>>>>> Am Sa., 19. Feb. 2022 um 10:54 Uhr schrieb Jörg Belger <unique75 at web.de <mailto:unique75 at web.de>>:
>>>>>>>> 
>>>>>>>> If somebody thinks know to use Github as source code repository, I like the idea only a little bit, Pharo uses it. It has the advantage that nobody needs to run an own server at home :-)
>>>>>>>> But the big disadvantage is, that you cannot think anymore in packages with its own version history like in Monticello. You need to think in repositories and branches and if you change two packages that are linked to one Github repository and you commit the first package, then I think you commit the second package too under the same version, because in reality you do not commit the package, you commit your current repository from disk to server. You lost the possibility to version each package differently.  That makes it impossible to load later packageA with version 1.5, but loading packageB with version 2.7.
>>>>>>>> 
>>>>>>> 
>>>>>>> To be honest, I do not see the problem here. Smalltalk version control
>>>>>>> systems almost all offer the feature of configuration maps because it
>>>>>>> is often required to specify which package versions work together
>>>>>>> because the packages in fact belong together. In Git and similarly
>>>>>>> organized version control systems, simply every commit is a
>>>>>>> configuration of the packages contained therein. If you do not change
>>>>>>> packageB on your new commit in which you want to change packageA,
>>>>>>> packageB in that new commit will be equal to packageB in the parent
>>>>>>> commit. It will not make a difference for packageB from which of the
>>>>>>> two commits you load it, so why care?
>>>>>>> 
>>>>>>> If you want to grab a change to one package from a commit but not a
>>>>>>> change to another package in the same commit -- for whatever reason
>>>>>>> that the maintainer apparently did not have in mind -- simply make a
>>>>>>> selective load/checkout: deselect the changes to the other package
>>>>>>> that you do not want to apply to the image, just as you would deselect
>>>>>>> changes that you do not want to commit when you create a new commit.
>>>>>>> Or the other way around: browse the commit from which you need some
>>>>>>> changes, select the package/category/class which you want, and load
>>>>>>> just that.
>>>>>>> 
>>>>>>> If the two packages are really not connected to each other and it is
>>>>>>> supported to freely combine different versions of them, then there is
>>>>>>> no point to develop them on the same branch or even in the same
>>>>>>> repository.
>>>>>>> 
>>>>>>>> Does anybody knows if we can have a Github repository where we can think like a Smalltalker and commit single packages ?
>>>>>>> 
>>>>>>> It is just a matter of organizing it as such. Create a new GitHub
>>>>>>> repository for each package and commit only one package to each
>>>>>>> repository. The repositories are already organized under your
>>>>>>> username. For everything beyond a single person, there are GitHub
>>>>>>> organizations like https://github.com/squeak-smalltalk/ <https://github.com/squeak-smalltalk/>. If you want
>>>>>>> to stay within a single Git repository for some reason, create a
>>>>>>> separate branch for each package and only commit a single package on
>>>>>>> each branch.
>>>>>>> 
>>>>>>> Kind regards,
>>>>>>> Jakob
>>>>>> 
>>>> 
>>>> 
>>> 
>>> 
>> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20220221/fd73b479/attachment.html>


More information about the Squeak-dev mailing list