Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Negative dependencies/conflicts? #122

Open
the-eater opened this issue Oct 16, 2022 · 4 comments
Open

Negative dependencies/conflicts? #122

the-eater opened this issue Oct 16, 2022 · 4 comments

Comments

@the-eater
Copy link

How can conflicts be implemented via this pubgrub package?

e.g. package A can only be installed if package B isn't there, or package A can only be installed if package B is at least version 5, but isn't a dependency of package A

@mpizenberg
Copy link
Member

Hello @the-eater. Conflicts, or also called constraints, can be expressed by the internal representation of pubgrub, by what are called "incompatibilities" in pubgrub but not by the currently exposed API. The guide provides a formal presentation of these in a dedicated section.
The gist is that an incompatibility is a set of terms, one per package, which cannot be true all together, at least one must be evaluated false. So if we call "any_version" the term referring to all existing versions of a given package, the constraint saying that package A can only be installed if package B isn't there would be expressed by the incompatibility:

{ A : any_version, B : any_version }

This means if any version of A is present, and any version of B is present, both terms are evaluated true and the incompatibility is called "satisfied" which is what the solver tries to avoid.

@the-eater I suggest you follow issue #120 as it is related to the same question and maybe there can be some collaboration there regarding interface discussions and implementations.

@Eh2406
Copy link
Member

Eh2406 commented Oct 16, 2022

Specifically, what is your practical use case? I want to make sure that whatever we design is ergonomic for real world needs.

@the-eater
Copy link
Author

Ah I will take a look!

@Eh2406 I am atm, writing a system package manager (ala apt-get, apk, xbps etc) where certain packages may conflict with each other because they provide the same functionality but with a different implementation say e.g. glibc and musl can't be installed alongside each other because they both provide libc.so (or a more real example the packages i3 and i3-gaps will conflict with each other because they both provide i3 but one is a fork with additional functionality)

the model of system package managers are in a sense also a bit different because there is less direct dependencies and more dependencies based on what a package provides, say e.g. bash doesn't depend on glibc but depends on the shared library libc.so.6, which glibc provides. while in the pubgrub model there seems to be the assumption of direct dependencies. (this however can be be worked around with adding package names to the versions, and replacing the package identifier with the concept of a "dependency specification")

So I'm not sure how good of a fit pubgrub actually is, but I have been interested in pubgrub for a while and think this could be a fitting application (even more so because of the clear conflict reporting)

@mpizenberg
Copy link
Member

mpizenberg commented Oct 16, 2022

I see. Well as you said nothing prevents you to have finer granularity on what you tell to pubgrub what "packages" are. You could tell libc is a "package" depending on either glibc or musl. When the solver gives you the final solution, you'd just need a way to differentiate actual packages from fake ones, with an enum or any other mean that suits you.

But when I say "you could" I mean hypothetically. Currently, depending on "either A or B" cannot be expressed with API of pubgrub v0.2. You can play smart with packages with the "bucket" trick as we call it in the guide to have something similar.

Otherwise, one such kind of constraint will require an incompatibility of the shape:

{ libc : v6, glibc : not(v6), musl : not(v1.2) }

This incompatibility forbids a situation where we have libc, and not glibc and not musl.
So if at any moment libc is required, it will try to pick glibc or musl. And if you have inside those the constraint:

{ glibc : any_version, musl : any_version }

It forbids situations where we have both glibc and musl installed.

Anyway, it's just to say that the base mechanism inside pubgrub, of "incompatibilities" is rather powerful, but currently we only expose a simple API, allowing only typical dependencies. Because it's always easier to start with simple case and improve later.

Thank you for expressing you use case, it's important to keep pubgrub as user-friendly as possible.
PS, this repo is currently on low maintenance mode as both @Eh2406 and me have not had a lot of time to work on this lately. The "release" branch corresponds to v0.2.1. But the dev branch already has code intended for v0.3, enabling better handling of more complex versioning, such as with pre-release tags. It needs documentation though. I think that will happen in november but no promess.

As for your use case, it's definitely related to #120 or at least will require similar loosening of pubgrub's API so it's great if you could participate in those design discussions.

@mpizenberg mpizenberg added this to the v0.4 milestone Oct 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants