Now I have some problems when releasing a new version of one library, I may have to change the dependencies of others and release new versions for them. For example: new version A means new version B, C and D.
- You have a multi repo approach.
- Edit A => new version A => bump version needed for B, C and D.
I think the most important thing is to avoid using dev-master and correctly configure your components correctly once they are stable and ready to exit the dev phase. You can then use the Composers range operators (caret ^ and tilde ~ ) to automatically upgrade to the latest version in a specific range of major.minor version. It helps a lot and you take the tedious manual version of the update from your hands.
- My explanation of how Laravel and Symfony solved the problem correctly?
- It is not right. The basic concept of development, publication and consumption of packages work differently, and then to what you described.
- They use a monolithic style of repo development. This is the only repository containing code for a group of packages. The opposite of
mono-repo is the many-repo approach. An alternative is git submodules . - All modules / nodes of the framework and core / core are in the same storage! For Laravel, this is https://github.com/laravel/framework/tree/5.4/src/Illuminate
- Each module / bundle folder contains
composer.json , and the framework itself contains composer.json - This allows you to "split" the folder modules into offline read-only storage. Using a special git helper, for example.
git subsplit publish as Laravel uses https://github.com/laravel/framework/blob/636020a96a082b80fa87eed07d45c74fa7a4ba70/build/illuminate-split-full.sh or splitsh https://github.com/splitsh/lite , as Symfony uses - The development is mainly repo.
- Finally, from the point of view of the user / consumer (in any case, in the composer.json of your CMS / application), you just need a module / package from a read-only offline storage source. This is a lot of repos because your application depends on many repositories.
When you update a dependency using Composer, Composer replaces your packages with a newer version.
- Do I need to remove tests from component repositories and put them in the framework?
No. You can also leave the tests in the /moduleA/tests folder and set up your unit test collector.
- If so, how can someone who just wants to use one component be sure that he passes the tests, regardless of whether the entire system that passes the tests for howling has passed?
Two things. Test object:
- (a) a component that is ideally independently tested and
- (b) a structure that consumes many components and testing functions that rely on functions from several components (e.g., kernel / kernel). You can also break the kernel as soon as it stabilizes and is independently verified. (e.g. your component D)
- Do I have to make sure that all dependency components are compatible and require them manually in composer.json format?
Monorepo Developer Perspective: A developer / supporter of a framework can only release a new version when all unit tests of all components and all unit tests of the platform itself pass, right? Then it can start splitting the subtree and automatically update new components.
Application Developer Perspective: Yes. As a user of monoreping components, you simply consume autonomous dependencies (from read-only repositories). This means that you need to maintain the versions of the components that are required in your composer.json manually or automatically.
- What is the point of having a component for interfaces? In any case, it is impossible to use it autonomously!
Good question!
It can be argued that interfaces are only development contracts. When all the components are written against the interfaces, you can just pull the plug on them, after testing and before creating the production release. In other words: you can leave the interface store and start removing the interface when you release it for production.
Exiting the repo interface will lead to fatal errors "X interfaces not found." Then you run the “optimizer run” over the rest of the classes and delete all the lines “implements the interface”. Fewer files to include. Less code to parse. Less I / O. And now I will probably be killed in the comments section by suggesting this :) And no, Laravel or Symfony do not.
- Is there a better way to solve this problem?
I suggest doing the following: for a project with <5 components, use multi-repo. If> 5 components, go to monorepo.
In general, there are not many options for solving this problem:
- git submodules
- mono repo
- multi repo
Each approach has pro and con .:
- Updating git submodules aka git updating the version and version submodule leads to git madness because it will be constantly broken. and git madness leads to the dark side. :)
- Mono repos are easy to maintain and easy to publish. This gives you easy developer support and multi-threading for the consumer. You can immediately replace / rename / refactor for all modules / components.
- Many repos are difficult to maintain when you have a large number of components.
See also: