Code refactoring
CLI
With the monorepo support, multiple dist-git repositories can be mapped to a single upstream monorepo.
Three different ways to modify our CLI existing code to support mapping one upstream repo with multiple dist-git repos have been researched.
get_packit_apito return multiplePackitAPIobjects: https://github.com/packit/packit/pull/1838.- deal with the package configs outside of
get_packit_api: https://github.com/packit/packit/pull/1840. - change
PackitAPI: not done.
Solution 3 has not been followed since a lot of code changes would have been required: to accomplish a koji build (as in the linked PR) we need to create new objects inside the PackitAPI which would bind togheter, as an examples, this attributes:
- https://github.com/packit/packit/blob/edfbde6e77552293e3c8888460b68f6726d5f115/packit/utils/changelog_helper.py#L52
- https://github.com/packit/packit/blob/edfbde6e77552293e3c8888460b68f6726d5f115/packit/cli/builds/koji_build.py#L92
and after having created this new objects inside PackitAPI we should change this existing lines of code and many others in the CLI commands.
We decided to follow one of solution 1 or 2 which have a much narrow code impact, try them out, and if they will not work we can discuss solution 3 later.
Solution 1 has two downsides:
- it binds together
PackitAPIandPackageConfigmanagement inside the methodget_packit_api: with the monorepo support, the effort to manage thePackageConfigwill increase a lot, for this reason probably it is better to move its management in a new class/method. - it returns a collection where before there was just a single object, so it has a broader impact on our code with respect of solution 2
Solution 2) has just one downsides:
- it uses a decorator which is not always easy to debug/understand.
Probably the best solution is the second one.
What is missing
PackageConfig management has to be improved. The CommonPackageConfig used by solution 1 and 2 is not complete. As an example it does not have the jobs details on it.
We should probably enrich the MultiplePackages object with new functionalities and probably create a new package config class. Something like a PackageConfigView that would mean, let me say, a package config viewed through the eyes of a single package in it.
Packit Service
The handlers in packit-service are using the JobConfig class to access most of the job data and the JobConfig objects, passed to an handler, are taken from the self.event.package_config.jobs call here and are used here.
I see two possible solutions to support monorepos.
For a
JobConfigreferencing multiple packages create as manyJobConfigView, here a draft example, as the packages but do not group them togetherSubstitute the
self.event.package_config.jobscalls like in this commit. Where thepackage_config.get_job_viewsmethod looks like this.The above solution resolves a test like this.
PROS: we don't need to touch much more code than this. Our handlers are designed to work with one
JobConfigand they will keep doing that, working in the same way with aJobConfigView(or just pick another name for it) and aJobConfig.CONS: if, for supporting monorepos, we need to deal with multiple packages in the same handler. Then we need to group together the
JobConfigViews, like in thepackage_config.get_grouped_job_viewsmethod here. And we should add a new way to match jobs and handlers insteve_job.process_jobsmethod. Create newsteve_job.get_handlers_for_eventandsteve_job.get_config_for_handler_klsmethods that instead of calling thesteve_job.get_jobs_matching_eventwill call a new method named something likesteve_job.get_grouped_jobs_matching_event. And thesteve_job.process_jobsat the end will create both the old handlers taking just oneJobConfigorJobConfigViewand also the brand new handlers taking a list ofJobConfigViews.
For a
JobConfigreferencing multiple packages create as manyJobConfigView, here a draft example, as the packages and group them togetherSubstitute the
self.event.package_config.jobswith a call like thepackage_config.get_grouped_job_viewshere. Modifysteve_job.process_jobs,steve_job.get_handlers_for_event,steve_job.get_config_for_handler_klsmethods to work with the new data structure returned by thepackage_config.get_grouped_job_views.At the end the
steve_job.process_jobswill create only handlers taking a list ofJobConfigorJobConfigViewand for this reason we will modify all our handlers to loop over all the given configs.PROS: one single way to match jobs and handlers
CONS: we are suggesting that all the handlers should be able to handle multiple configs, but this is probably not true.
Personally I prefer solution 1. I see it as more simple and explicit. We probably could/should re-think the job/handler matching code from the point of view of a monorepo. I feel like it is worth doing that when we have a clear understanding of what we need in a handler capable of supporting multiple packages.